环境要求
spring对AOP的支持
*如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
* 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
*如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP?
* 添加CGLIB库,SPRING_HOME/cglib/*.jar
* 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK动态代理和CGLIB字节码生成的区别?
* JDK动态代理只能对实现了接口的类生成代理,而不能针对类
* CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
下面就看看怎么用JDK、CGLib的方式实现动态代理
首先先看下
UserManager接口
- package com.macower.spring.proxy;
-
-
public interface UserManager {
-
public void addUser(String id, String password);
-
public void delUser(String id);
- }
接下来是其实现类 UserManagerImpl
- package com.macower.spring.proxy;
-
-
public class UserManagerImpl implements UserManager {
-
-
public void addUser(String id, String password) {
-
System.out.println(".: 掉用了UserManagerImpl.addUser()方法! ");
-
- }
-
-
public void delUser(String id) {
-
System.out.println(".: 掉用了UserManagerImpl.delUser()方法! ");
-
- }
- }
JDK动态代理类
- package com.macower.spring.proxy;
-
import java.lang.reflect.InvocationHandler;
-
import java.lang.reflect.Method;
-
import java.lang.reflect.Proxy;
-
-
-
-
-
-
-
public class JDKProxy implements InvocationHandler {
-
-
private Object targetObject;
-
-
public Object newProxy(Object targetObject) {
-
this.targetObject = targetObject;
-
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
-
targetObject.getClass().getInterfaces(), this);
- }
-
-
public Object invoke(Object proxy, Method method, Object[] args)
-
throws Throwable {
-
checkPopedom();
-
Object ret = null;
-
ret = method.invoke(targetObject, args);
-
return ret;
- }
-
-
private void checkPopedom() {
-
System.out.println(".:检查权限 checkPopedom()!");
- }
- }
CGLibProxy动态代理类
- package com.macower.spring.proxy;
-
-
import java.lang.reflect.Method;
-
-
import net.sf.cglib.proxy.Enhancer;
-
import net.sf.cglib.proxy.MethodInterceptor;
-
import net.sf.cglib.proxy.MethodProxy;
-
-
-
-
-
-
-
-
public class CGLibProxy implements MethodInterceptor {
-
-
private Object targetObject;
-
-
public Object createProxyObject(Object obj) {
-
this.targetObject = obj;
-
Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(obj.getClass());
-
enhancer.setCallback(this);
- Object proxyObj = enhancer.create();
-
return proxyObj;
- }
-
-
public Object intercept(Object proxy, Method method, Object[] args,
-
MethodProxy methodProxy) throws Throwable {
-
Object obj = null;
-
if ("addUser".equals(method.getName())) {
-
checkPopedom();
- }
- obj = method.invoke(targetObject, args);
-
return obj;
- }
-
-
private void checkPopedom() {
-
System.out.println(".:检查权限 checkPopedom()!");
- }
- }
下面来测试下
- package com.macower.spring.proxy;
-
-
public class Client {
-
-
public static void main(String[] args) {
-
-
UserManager userManager = (UserManager) new CGLibProxy()
-
.createProxyObject(new UserManagerImpl());
-
System.out.println("-----------CGLibProxy-------------");
-
userManager.addUser("Macower", "root");
-
System.out.println("-----------JDKProxy-------------");
-
JDKProxy jdkPrpxy = new JDKProxy();
- UserManager userManagerJDK = (UserManager) jdkPrpxy
-
.newProxy(new UserManagerImpl());
-
userManagerJDK.addUser("Macower", "root");
- }
-
- }
执行结果是:
- -----------CGLibProxy-------------
- .:检查权限 checkPopedom()!
- .: 掉用了UserManagerImpl.addUser()方法!
- -----------JDKProxy-------------
- .:检查权限 checkPopedom()!
- .: 掉用了UserManagerImpl.addUser()方法!
JDK代理是不需要以来第三方的库,只要要JDK环境就可以进行代理,它有几个要求
* 实现InvocationHandler
* 使用Proxy.newProxyInstance产生代理对象
* 被代理的对象必须要实现接口
CGLib 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承
但是针对接口编程的环境下推荐使用JDK的代理
在Hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的相关代理采用的是CGLib来执行
所以在是实际的开发当中,开发人员应该根据实际的需求来选择合适的代理工具。
相关推荐
赠送jar包:spring-plugin-core-2.0.0.RELEASE.jar; 赠送原API文档:spring-plugin-core-2.0.0.RELEASE-javadoc.jar;...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
使用SpringCloud Zuul Proxy构建API网关.docx
此压缩文件中包含spring的如下组件的doc,source,jar: spring-aop-4.1.6.RELEASE.jar spring-aspects-4.1.6.RELEASE.jar spring-beans-4.1.6.RELEASE.jar spring-context-4.1.6.RELEASE.jar spring-context-...
spring 3.2.4 Realease 的所有jar包: spring-context-3.2.4.RELEASE.jar spring-core-3.2.4.RELEASE.jar spring-beans-3.2.4.RELEASE.jar spring-test-3.2.4.RELEASE.jar spring-web-3.2.4.RELEASE.jar spring-aop-...
网上能找到同样的资源,但是兼容了jdk1.8,在jdk1.6下运行就会报错了。此jar包 兼容jdk1.6、jdk1.7、jdk1.8,仅仅修改了org.springframework.core.JdkVersion这个类,请放心使用。
Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....
(jdk1.8和spring4)\cglib-2.2.2.jar, 287192 , 2019-03-06 (jdk1.8和spring4)\commons-dbcp-1.2.2.jar, 121757 , 2019-03-06 (jdk1.8和spring4)\commons-logging-1.1.1.jar, 60686 , 2019-03-06 (jdk1.8和...
jdk7SpringMVC 13个核心jar包大集合 包括 1.spring-aop-3.2.0.RELEASE.jar 2.spring-aspects-3.2.0.RELEASE.jar 3.spring-beans-3.2.0.RELEASE.jar 4.spring-context-3.2.0.RELEASE.jar 5.spring-context-support-...
spring 4.0.0 框架核心包 aopalliance-1.0.jar spring-aop-4.0.0.RELEASE.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0....
spring data jpa的包。spring-data-commons-1.8.0.RELEASE.jar
spring-data-commons-1.7.2.RELEASEspring-data-jpa-1.5.2.RELEASE-java datajpa
proxy,jdkproxy-transaction,jdkproxy-salary,day02-itheima11-spring-08-cglibproxy,day02-itheima11-spring-09-aop.xml,day02-itheima11-spring-10-aop.xml.advice,day02-itheima11-spring-11-aop.xml.exception等...
解决“annotation-config are only available on JDK 1.5 and higher”的问题!
spring-cglib-repack-3.2.5.jar,
jar包清单: aopalliance.jar aspectjweaver-1.8.2.jar commons-beanutils.jar commons-collections-3.1.jar commons-lang-2.3.jar commons-logging-1.1.3.jar ...org.springframework.web-3.0.0.RELEASE.jar
API帮助文档CHM中文版JDK,MyBatis,Spring,Servlet全是CHM版本...
org.springframework.aop-3.0.4.RELEASE.jar org.springframework.asm-3.0.4.RELEASE.jar org.springframework.aspects-3.0.4.RELEASE.jar org.springframework.beans-3.0.4.RELEASE.jar org.springframework....
Spring集成MongoDB官方指定jar包:spring-data-mongodb-1.4.1.RELEASE.jar
该jar包兼容了jdk1.3到1.8,可以放心使用。
赠送jar包:spring-boot-2.3.12.RELEASE.jar; 赠送原API文档:spring-boot-2.3.12.RELEASE-javadoc.jar; 赠送源代码:spring-boot-...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。