注:SpringAOP默认使用的是JDK Proxy动态代理,如需CGLIB需要配置
配置文件开启CGLIB:
<aop:config proxy-target-class="true" /> 默认falce JDKProxy
注解开启
<aop:aspectj-autoproxy proxy-target-class="true" />
注解开启:
@EnableAspetJAutoProxy(proxyTargetClass = true)
JDK Proxy:
- 在不改变目标对象方法的情况下对方法进行增强
- 组成:
- 被代理对象:真实对象
- 代理对象:内存中的一个对象
- 要求:
- 代理对象必须和被代理对象实现相同接口
- 实现:
- Proxy.newProxyInstance():
- 参数1:和被代理对象使用相同类加载器:被代理对象.getClass().getClassLoader()
- 参数2:Class数组(和被代理对象使用相同接口),new Class[]{被代理对象接口.class}
- 参数3:代理规则 new InvocationHandler()匿名内部内
- Proxy.newProxyInstance():
public class Test {
public static void main(String[] args) {
final Student student = new Student();
/*
类加载器:和被代理对象使用相同的类加载器
接口类型的class数组:和被代理对象使用相同的接口
代理规则:完成代理增强的功能
*/
StudentInterface proxyStu = (StudentInterface) Proxy.newProxyInstance(student.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() {
/*
执行Student类中所有方法都会经过invoke方法
method:被代理对象的方法
args:被代理对象传递的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("study")) {
System.out.println("测试测试");
return null;
}else {
return method.invoke(student,args);
}
}
});
proxyStu.eat("米饭");
proxyStu.study();
}
}
代理规则:
所有方法都会经过代理规则的invoke方法,可在方法内对当前执行的方法进行判断
ps:根据自己写的方法,动态生成一个内存中的地址,执行时会先调用自己写的方法返回给动态代理,在invoke这里被拦截
—————————————————————————————————————————————————————————————
案例:
原始方法
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("测试一");
}
}
Proxy类:
1、首先new一个InvocationHandler对象(参数1:原始对象,参数2:原始对象接口数组,参数3:规则)
参数1:使用ClassLoader cl = userService.getClass().getClassLoader();获取原始对象
参数2:使用Class[] classes = userService.getClass().getInterfaces(); getInterfaces获取原始方法所有接口
参数3:规则:invoke方法,首先调用原始方法(传入原始对象接口,参数)
public class UserServiceJDKProxy {
public static UserService createUserServiceJDKProxy(UserService userService) {
ClassLoader cl = userService.getClass().getClassLoader();
Class[] classes = userService.getClass().getInterfaces();
InvocationHandler ih = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = method.invoke(userService, args);
System.out.println("测试二");
System.out.println("测试三");
return ret;
}
};
UserService service = (UserService) Proxy.newProxyInstance(cl,classes,ih);
return service;
}
}