代理对象:target / targetSource
代理逻辑:advice
代理方法:pointCut
代理逻辑+代理方法:advisor
演变过程:
使用cglib或者jdk的动态代理
——(提供一个类,封装cglib和jdk动态代理的选择)——>
ProxyFactory是这样的类,通过proxyFactory.getProxy获取代理对象
——(proxyFactory能否成为bean)——>
使用ProxyFactoryBean可以从spring容器中通过被代理对象的名称获取代理对象
——(能否选择bean作为target,而不是new一个对象;选择bean作为advice,而不是new)——>
BeanNameAutoProxyCreator能解决这个问题
——(能否指定被代理bean的具体方法)——>
DefaultPointcutAdvisor能设置方法名称,将包含此方法的bean都生成aop代理对象
——(能否即指定bean作为被代理对象,又能指明该bean的被代理方法)——>
@Aspect注解方式
spring aop过程总结:
Advisor:
PointCut
ClassFilter
MethodMatcher
Advice--->Method拦截器
被代理类--->找到所有匹配的Advisor---->利用proxyFactory生成代理对象
代理对象执行某个方法时---->依赖当前调用的方法---->找到所匹配的advisor----->执行对应的advice逻辑
附录:
@Bean
public ProxyFactoryBean userService(){
UserService userService = new UserService();
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(userService);
proxyFactoryBean.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
});
return proxyFactoryBean;
}
获取被代理对象的方法:
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserInterface userService = (UserInterface) applicationContext.getBean("userService");
userService.test();
}
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("userSe*");
beanNameAutoProxyCreator.setInterceptorNames("myAroundAdvice");
beanNameAutoProxyCreator.setProxyTargetClass(true);
return beanNameAutoProxyCreator;
}
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(){
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("test");
DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new ZhouyuAfterReturningAdvice());
return defaultPointcutAdvisor;
}