Определение концепции
Advice
определение: что делать
PointCut
определение: где делать
Advisor
определение: Советы по сборке и PointCut, где что делать
Процесс запуска АОП
AopAutoConfiguration
Начните с автоматической настройки SpringBoot aop
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
public static class CglibAutoProxyConfiguration {
}
}
Вы можете использовать **@EnableAspectJAutoProxy** для включения автоматического прокси-сервера aop.
В соответствии со свойством spring.aop.proxy-target-class решите, следует ли использовать cglib для создания прокси.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//是否使用cglib方式生成代理,默认使用jdk代理方式
boolean proxyTargetClass() default false;
//TODO 暂时不知道啥用
boolean exposeProxy() default false;
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
//通过参数传入BeanDefinitionRegistry对象,自行注册需要的BeanDefinition
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册AutoProxyCreator到容器中
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//解析@EnableAspectJAutoProxy属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//使用cglib代理
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//TODO 不知道啥用
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
#org.springframework.aop.config.AopConfigUtils
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
//判断容器中是否已经注册AUTO_PROXY_CREATOR_BEAN_NAME
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//没啥用,不用看
...
return null;
}
//容器中没有AUTO_PROXY_CREATOR_BEAN_NAME的定义,注册到容器中
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
Краткое описание процесса:
- Зарегистрируйте org.springframework.aop.config.internalAutoProxyCreator в контейнере.
注意:org.springframework.aop.config.internalAutoProxyCreator只是BeanDefintion的名字而已,不是一个类名.其对应的真实类是org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
Взгляните на семейный портрет AbstractAutoProxyCreator.
Из семейного портрета видно, что классы реализации AutoProxyCreator условно делятся на два типа:
- На основе стандартных концепций АОП (Advice, PointCut)
- Сопоставление по имени
从上面的全家福中可以看到以上3个都是属于第一种的,为何AopConfigUtils只提供了这3中AutoProxyCreator的注册? TODO暂时给不出解释
Процесс создания агента
догадка: время создания прокси-объекта должно состоять в том, чтобы найти соответствующий аспект после завершения создания экземпляра, а затем собрать его в прокси-объект.
На основании этой спекуляции мы находим внедрение BeanPostProcessor.PostProcessaferinitiationAtization () в абстрактныйautoProxyCreator.
AbstractAutoProxyCreator是个抽象类,并实现了几个Spring生命周期方法(模板方法模式)
#AbstractAutoProxyCreator
//对象实例化完成之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
//缓存
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//创建代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//抽象,匹配切面
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Краткое описание процесса:
-
Получите соответствующий совет
切面匹配过程,下面会详细讲
-
Weave Advice, сгенерируйте прокси
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); //是否使用cglib生成代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } //添加Advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { proxyFactory.addAdvisor(advisor); } //创建代理 return proxyFactory.getProxy(getProxyClassLoader()); } protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) { //公共Interceptor Advisor[] commonInterceptors = resolveInterceptorNames(); //commonInterceptors+specificInterceptors List<Object> allInterceptors = new ArrayList<Object>(); ... Advisor[] advisors = new Advisor[allInterceptors.size()]; ... return advisors; } #org.springframework.aop.framework.ProxyFactory public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } #org.springframework.aop.framework.ProxyCreatorSupport protected final synchronized AopProxy createAopProxy() { ... return getAopProxyFactory().createAopProxy(this); } #org.springframework.aop.framework.DefaultAopProxyFactory public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //是否使用cglib进行代理 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //cglib代理 return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
具体的Proxy对象生成过程我们暂且不看
Выше показан процесс создания прокси с помощью AbstractAutoProxyCreator.
Давайте посмотрим, как два лагеря, основанные на стандарте АОП и на сопоставлении имен, получают аспекты.
Процесс сопоставления аспектов
На основе стандарта АОП
#org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//抽象,获取可能匹配的Advice
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//抽象,获取合格的Advice
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//对Advice进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
На основе интерфейса советника
#org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
#org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper
public List<Advisor> findAdvisorBeans() {
//返回所有Advisor接口的实现类
String[] advisorNames = null;
...
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
...
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
...
advisors.add(this.beanFactory.getBean(name, Advisor.class));
...
}
return advisors;
}
На основе аннотаций AspectJ
#org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
@Override
protected List<Advisor> findCandidateAdvisors() {
//获取基于Advisor接口的实现类
List<Advisor> advisors = super.findCandidateAdvisors();
//另加入基于AspectJ注解的Advisor(通过适配器模式包装成一个Advisor)
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
#org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder
public List<Advisor> buildAspectJAdvisors() {
//1.从工厂中获取所有带有@Aspect注解的实现类
//2.解析其中所有方法上的注解
//3.通过适配器模式包装成Advisor返回
//过程不过多分析
....
return advisors;
}
Сопоставление по имени
#org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
if (this.beanNames != null) {
for (String mappedName : this.beanNames) {
//如果匹配则返回
if(){
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}
}
//名称不匹配则返回DO_NOT_PROXY标志位 ,不进行代理
return DO_NOT_PROXY;
}
BeanNameAutoProxyCreator只能对所有注册的BeanName适用相同的Interceptor