Spring
的代理在上层中主要分为ProxyCreatorSupport
和ProxyProcessorSupport
,前者是基于代理工厂,后者是基于后置处理器,也能够认为后置就是自动代理器。当spring
容器中须要进行aop
进行织入的bean
较多时,简单采用ProxyFacotryBean
无疑会增长不少工做量(由于每一个Bean
!都得手动写一个)。因此自动代理就发挥它的做用了。java
在内部,Spring使用BeanPostProcessor
让自动生成代理。基于BeanPostProcessor的自动代理建立器的实现类,将根据一些规则在容器实例化Bean
时为匹配的Bean生成代理实例。代理建立器能够分为三类:git
BeanNameAutoProxyCreator
Advisor
匹配机制的自动代理建立器它会对容器中的全部Advisor进行扫描,自动将这些切面应用到匹配的Bean中,实现类是DefaultAdvisorAutoProxyCreator
(它也支持前缀匹配) AspectJ
注解的自动代理生成器:为包含AspectJ注解的切入的Bean自动建立代理实例,实现类是AnnotationAwareAspectJAutoProxyCreator
,它是咱们的@EnableAspectJAutoProxy
导入的,这也是咱们当下使用最为普遍的方式~ package com.github.dqqzj.springboot.aop;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @author qinzhongjian
* @date created in 2019-08-25 09:43
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
@Component
public class MyBeanNameAutoProxyCreator extends BeanNameAutoProxyCreator {
@PostConstruct
public void init() {
super.setBeanNames("aopService", "abstractAutoProxyCreatorService");
super.setInterceptorNames("myMethodBeforeAdvice");
}
}复制代码
若是你想用本身注册的@Bean
代替@EnableAspectJAutoProxy
默认给你注册的自动建立器AnnotationAwareAspectJAutoProxyCreator
,那么你能够注册一个Bean名称以下的Bean便可:github
// 手动注册一个自动代理建立器,且名字务必叫AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME
@Bean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME)
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
...
}复制代码
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
}复制代码
AbstractAutoProxyCreator
是对自动代理建立器的一个抽象实现。最重要的是,它实现了SmartInstantiationAwareBeanPostProcessor
接口,所以会介入到Spring IoC
容器Bean实例化的过程,在AbstractAutowireCapableBeanFactory
中有这样一段代码spring
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}复制代码
可是通常都不会生效的,由于这个resolveBeforeInstantiation
只是针对有自定义的targetsource
,由于自定义的targetsource
不是spring的bean那么确定不须要进行后续的一系列的实例化 初始化。因此能够在resolveBeforeInstantiation直接进行proxy
。简单的说吧 ,这个代码能够忽略不计,开发者通常用不到。springboot
package com.github.dqqzj.springboot.aop;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
/**
* @author qinzhongjian
* @date created in 2019-08-25 11:35
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
public class AopServiceInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass.isInstance(AopService.class)) {
return new AopService();
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}复制代码
这个是spring
第一次后置处理器的使用,若是这样直接就返回了,就至关于脱离了IOC
的生命周期了同样,依赖注入,属性填充等这些都没有进行处理,因此使用的时候必定要注意,最好别使用这个功能。架构
在初始化bean的过程当中后续还有2个特别重要的后置处理过程,对于循环依赖甚至异步注解事物注解等都有或多或少的影响,后续会继续分析它们。异步
SpringAOP
应尽可能避免本身建立AutoProxyCreator
,内部机制及其复杂不免会因为没有想到的问题而出现其余不常见的问题,上面分享的内容不多,缘由是我以为熟悉这个架构设计师最关键的,各类子类的虽然实现大不相同,可是你想所有都记在脑海或者很熟悉那是不太现实的,只有熟悉他的设计才能碰见问题轻易的就能翻源码解决。ide