public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator
一、使用
/**
*模拟业务接口
*/
public interface UserService {
public void updateUser();
}
/**
*模拟具体业务
*/
public class UserServiceImpl implements UserService{
@Override
public void updateUser() {
System.out.println("$$$$$$执行业务逻辑$$$$$");
}
}
/**
* 模拟切面1
*/
public class SecurityInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("==========执行安全校验====================");
return methodInvocation.proceed();
}
}
/**
* 模拟切面2
*/
public class LoggerBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("=======保存更新日志=========");
}
}
<beans>
<bean class="org.springaop.chap01.UserServiceImpl" id="userService"></bean>
<bean class="org.springaop.chap01.LoggerBeforeAdvice" id="loggerBeforeAdvice"></bean>
<bean class="org.springaop.chap01.SecurityInterceptor" id="securityInterceptor"></bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>userService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>loggerBeforeAdvice</value>
<value>securityInterceptor</value>
</list>
</property>
</bean>
</beans>
结果:
=======保存更新日志=========
$$$$$$执行业务逻辑$$$$$
二、剖析BeanNameAutoProxyCreator设计
类&接口 | 作用 |
---|---|
Ordered | 定义顺序的,影响Processor的执行顺序,默认为“LOWEST_PRECEDENCE”,可以自己指定 |
Aware*类 | 感知接口,与Spring容器沟通的手段 |
*BeanPostProcessor | 影响spring Bean的生命周期,在对应生命周期中调用,是生成代理对象的入口 |
AopInfrastructureBean | 表示该类是Spring AOP支持对象,仅仅是个标识 |
ProxyConfig | 是一个类,保存了代理配置元信息,影响代理生成行为 |
我们知道了Spring生成代理时,需要2个重要的信息,一个是源对象targetSource,一个是Advisor列表。
1.Spring应该是从Spring容器中,根据咱们声明的beanNames属性,当成源对象,然后代理包装
2.Advisor列表,也是从Spring容器中获取,和interceptorNames相关。
3.剖析BeanNameAutoProxyCreator实现
3.1Spring怎么完成BeanName的匹配的。
这段代码仅仅把beanName放入一个List中
抽象类中AbstractAutoProxyCreator里面有个getAdvicesAndAdvisorsForBean()方法。这个方法会在spring的生命周期。beanPost中postProcessBeforeInstantiation被调用。
核心的匹配代码。匹配成功。则这个类需要被代理。
4.Advisor列表初始化
//2
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
...
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
...
return proxyFactory.getProxy(this.proxyClassLoader);
}
