前置知识:spring 使用aspectJ实现了aop,听起来好像spring的aop完全是依赖于aspectJ,其实spring对于aop的实现是通过动态代理(jdk的动态代理或者cglib的动态代理),它只是使用了aspectJ的Annotation,并没有使用它的编译器和织入器,进行注解的解析工作是Spring内部实现的,所以Spring AOP只是借助了AspectJ的注解而已。
spring AOP提供两种编程风格
@AspectJ support ------------>利用aspectj的注解
Schema-based AOP support ----------->xml aop:config 命名空间
开始源码剖析:
首先,要开启aop需要使用@EnableAspectJAutoProxy注解
@EnableAspectJAutoProxy
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 使用@import将想要注册的类注册到容器中,没有标注@Component的普通类也能被注入进来
// 导入注册器,实际上是通过调用该注册器的方法,注册beanDefinition
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册AnnotationAwareAspectJAutoProxyCreator的beanDefinition ,主要方法
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//2.获取原注解也就是EnableAspectJAutoProxy上面设置的属性值
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
//3.设置proxyTargetClass属性
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//4.设置exposeProxy属性
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
第1步注册一个AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,此步骤很关键,具体看代码块3中的registerAspectJAnnotationAutoProxyCreatorIfNecessary的源码,第2、3、4步就是向AnnotationAwareAspectJAutoProxyCreator的BeanDefinition设置属性的步骤,看一下第3步和第四步设置proxyTargetClass属性和设置exposeProxy属性
registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary()
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
registerOrEscalateApcAsRequired()
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断beanDefinitionMap中是否已经包含了名称为"org.springframework.aop.config.internalAutoProxyCreator"的beanDefinition
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
// 如果包含了就从容器中获取
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
//5.如果名称不一样,则获取优先级,在这里我们知道cls传过来的是AnnotationAwareAspectJAutoProxyCreator这个类,
//而这个AnnotationAwareAspectJAutoProxyCreator的优先级是最高的,如果名称不一样,则BeanClassName则会被替换成
//AnnotationAwareAspectJAutoProxyCreator.class的名称
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
// beanDefinitionMap中没有包含名称为"org.springframework.aop.config.internalAutoProxyCreator"的beanDefinition就进行创建
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
// 向容器中注入该beanDefinition
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
// 返回创建好的beanDefinition
return beanDefinition;
}
}
forceAutoProxyCreatorToUseClassProxying(registry)
forceAutoProxyCreatorToExposeProxy(registry)
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
//1.如果容器中包含AUTO_PROXY_CREATOR_BEAN_NAME的BeanDefinition,则设置proxyTargetClass属性为true,
//该属性在创建动态代理的时候,会影响使用JDK还是CGLIB来实现动态代理
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
看一下AnnotationAwareAspectJAutoProxyCreator类的继承关系图
到此就完成了向Spring容器中注入了一个封装了AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对象,我们可以看到AnnotationAwareAspectJAutoProxyCreator间接的实现了InstantiationAwareBeanPostProcessor接口和BeanPostProcessor接口,也就是说在bean的生命周期中AnnotationAwareAspectJAutoProxyCreator也会参与进来,依据前面分析过的,InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法作为第一个被执行的后置处理器方法,postProcessAfterInstantiation()是第五个被执行的后置处理器方法;BeanPostProcessor接口postProcessBeforeInitialization方法和postProcessAfterInitialization方法是第七、八个被执行的后置处理器方法,AnnotationAwareAspectJAutoProxyCreator中只有上述postProcessBeforeInstantiation和postProcessAfterInitialization方法的具体实现。
在bean被实例化之前,调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法(实际上是调用父类AbstractAutoProxyCreator的重写方法)。我们来看:
AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation
判断要不要在此处直接生成代理对象,并返回,不进行bean的整个创建过程,直接将返回的对象,放入单例池。一般情况下,如果我们没有自己配置TargetSourceCreator,则一定会返回null。不会进入,就不详细分析了。
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
return null;
}
}
真正代理方法的执行是在initializeBean方法中进行的,当bean经历了实例化,属性填充之后,就会来到初始化的步骤,在这里面,会调用BeanPostProcessor后置处理器的postProcessBeforeInitialization和postProcessAfterInitialization方法,代理方法的执行也是在postProcessAfterInitialization进行的。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
//1.已存在bean,这个bean是没有代理之前的bean
Object result = existingBean;
Object current;
//2.拿到所有的bena的后置处理器,依次进行遍历
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
//3.执行其postProcessAfterInitialization方法
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessBeforeInitialization(result, beanName);
//4.如果有其中一个返回空,则就直接返回了,不再进行遍历
if (current == null) {
return result;
}
}
return result;
}
第3步执行后置处理器的postProcessAfterInitialization方法,并将返回的current 对象赋值给result,也就是会替换原来的bean对象。而对于bean后置处理器的postProcessAfterInitialization方法,如果不做处理的话,都是直接将传递过来的bean给直接返回,而不进行任何处理。 AnnotationAwareAspectJAutoProxyCreator也是一个bean后置处理器,而AnnotationAwareAspectJAutoProxyCreator间接的继承AbstractAutoProxyCreator类,在AbstractAutoProxyCreator类中实现了postProcessAfterInitialization方法
AbstractAutoProxyCreator#postProcessAfterInitialization方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//1.获取缓存键,如果beanName没有长度,则直接返回bean的class,如果不为空,
//会判断当前bean是否为FactoryBean的子类,如果是,则在其bean名称前面添加&, 如果不是则直接返回bean的名称,
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
// 从earlyProxyReferences中移出缓存key,我们看一下哪里用到了缓存key↓,==判断是否已经代理过了==,代理过了就直接返回原来的bean,如果代理过了,会在再次调用getSingleton()时,从二级缓存中获得
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object getCacheKey(Class> beanClass, @Nullable String beanName) {
// 判断beanName是不是空字符串,有长度,如果有就判断是不是工厂bean,如果是工厂bean,就返回&beanName,否则返回原来的beanName
if (StringUtils.hasLength(beanName)) {
return FactoryBean.class.isAssignableFrom(beanClass) ? "&" + beanName : beanName;
} else {
return beanClass;
}
}
private final Map
wrapIfNecessary()看一下具体进行代理增强的代码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
// 1.获取能够使用的排序后的通知数组
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
// 2.如果数组不为null,表明需要进行代理,进入if判断
if (specificInterceptors != DO_NOT_PROXY) {
// 3.向已经完成通知的bean的map中添加缓存键和是否需要进行增强的标志,标志为true,表明需要进行增强,(此时还未进行增强,即将要增强了...)
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 4.创建代理对象
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
// 6.在这可以看到即使不需要增强,只要经过了是否需要增强的判断,就会被添加到Map集合中,只不过标志为false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 1.1查找所有符合条件的并且经过排序的通知列表
List advisors = this.findEligibleAdvisors(beanClass, beanName);
// 1.2如果不为空,就将通知列表转为数组后返回,如果为空不进行代理返回null
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
// 寻找符合条件的通知对象列表
protected List findEligibleAdvisors(Class> beanClass, String beanName) {
// 1.先看下面:有下面的分析可知,此处就是生成全部Advisor的地方了,在这就能拿到不论是注解定义还是实现Advisor接口的全部封装好的Advisor增强器,其内部主要封装了pointcut(要被增强的方法)以及advise(实际去增强的内容)
List candidateAdvisors = this.findCandidateAdvisors();
// 2.选择该bean能够使用的增强器列表,也就是切点所在的类是当前bean对应的类的,[此处事务的Advisor中的pointcut回去进行匹配判断,会利用AnnotationTransactionAttributeSource去检查类上是否有@Transactional注解,检查方法上是否有@Transactional注解,有就将其添加到可用的Advisor列表中]
List eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 如果可用的通知不为空就对其进行排序,排序会按照下面的规则进行排序
/**
-1 ExposeInvocationInterceptor#invoke
0 事务advisor
1.环绕增强前(around advice before)
2.前置增强(before advice)
3.-- 方法执行
4.环绕增强后(around advice after)
5.后置finally增强(after advice)
6.后置增强/抛出增强
**/
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
// 返回排序后的可用的通知列表
return eligibleAdvisors;
}
看一下候选通知列表:
看一下筛选前后的:
看一下排序之后的:
看一下advisedBeans里面的内容:
findCandidateAdvisors()
protected List findCandidateAdvisors() {
// 此步为止如果没有自定义实现Advisor接口的类,并且没有开启事务,如果开启了事务,会自动注册一个事务相关的advisor,只是通过注解进行了配置@Aspect,那就会advisors返回null
List advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
// 此步是主要的去构建Advisor的步骤
// 将搜索到的全部的带有Aspect注解的类中的带有@Before。@After等注解的方法,以及其切入点(要增强的方法)都封装成了Advisor,与之前搜索到了通过实现Advisor接口的形式定义的Advisor整合,获取到全部的Advisor增强器。====================重点=============================
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
buildAspectJAdvisors()
public List buildAspectJAdvisors() {
// 此处获取advisor类型的beanName
List aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized(this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List advisors = new ArrayList();
List aspectNames = new ArrayList();
// 此处就是去获取全部被注册的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
String[] var18 = beanNames;
int var19 = beanNames.length;
// 遍历每一个beanName
for(int var7 = 0; var7 < var19; ++var7) {
String beanName = var18[var7];
// 默认返回true
if (this.isEligibleBean(beanName)) {
Class> beanType = this.beanFactory.getType(beanName, false);
// 判断当前类型是不是Aspect类型,就是判断是否存在Aspect注解,不存在就继续遍历下一个
/**
public boolean isAspect(Class> clazz) {
return this.hasAspectAnnotation(clazz) && !this.compiledByAjc(clazz);
}
**/
if (beanType != null && this.advisorFactory.isAspect(beanType)) {
// 找到了,就添加带有Aspect注解的beanName到aspectNames中
aspectNames.add(beanName);
// 将其封装为aspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析beanName对应的类中的方法,将通知(标有注解的before、after....)和相对应的切点都封装成Advisor返回,如下图,看一下结构
List classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 是单例bean将其,以及它对应的Advisor放入缓存中
this.advisorsCache.put(beanName, classAdvisors);
} else {
this.aspectFactoryCache.put(beanName, factory);
}
// 将其全部添加到Aspect列表中并返回
advisors.addAll(classAdvisors);
} else {
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
} else {
List advisors = new ArrayList();
Iterator var3 = aspectNames.iterator();
while(var3.hasNext()) {
String aspectName = (String)var3.next();
List cachedAdvisors = (List)this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
beanNamesForTypeIncludingAncestors
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class> type, boolean includeNonSingletons, boolean allowEagerInit) {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
// 可以看到此处传入的type是Object.class,所以result此时拿到的是全部被注册了的beanName
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
// 我们的创建的bean工厂是HierarchicalBeanFactory类型的
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory)lbf;
// 我们没有在自己的beanFactory中添加ParentBeanFactory,所以默认为null
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors((ListableBeanFactory)hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
result = mergeNamesWithParent(result, parentResult, hbf);
}
}
// 返回全部的beanName数组
return result;
}
AspectMetadata结构
classAdvisors的结构
至此已经获取了全部的Advisor增强器,接下来就是筛选、排序、创建代理了......
createProxy()创建代理对象
protected Object createProxy(Class> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取使用@EnableAspectJAutoProxy开启代理时,设置的属性,比如proxyTargetClass(是否使用目标类进行代理--cglib,默认是false,也就是说默认采用的时jdk的动态代理),exposeProxy等
proxyFactory.copyFrom(this);
// 判断是否使用目标类进行动态代理
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass)) {
Class[] var6 = beanClass.getInterfaces();
int var7 = var6.length;
for(int var8 = 0; var8 < var7; ++var8) {
Class> ifc = var6[var8];
proxyFactory.addInterface(ifc);
}
}
// 判断是否应该使用动态代理,这里面是在判断beanDefinition的attributes中是否已经标志过要使用目标类进行动态代理了(一般不存在,需要手动设置)
} else if (this.shouldProxyTargetClass(beanClass, beanName)) {
// 如果被标记过了,就设置使用目标类进行代理
proxyFactory.setProxyTargetClass(true);
} else {
// 评估代理接口:
/**
首先获取全部的该bean的实现接口,遍历这些接口,这些接口中只要有一个通过(!this.isConfigurationCallbackInterface(ifc) && !this.isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0)判断,就表明存在合理的接口,将这些接口添加到代理工厂中,否则就将其设置为使用目标类代理
**/
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
// 将前面经过选择和排序的拦截器数组,以及后面解析到的拦截器等构建成统一的Advisor类型,来对对象进行增强
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置需要进行代理的类
proxyFactory.setTargetSource(targetSource);
// 空方法
this.customizeProxyFactory(proxyFactory);
// 用来控制代理工厂被配置之后,是否还允许修改通知
// 默认值为false(即在代理被配置之后,不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = this.getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
}
// 创建代理对象
return proxyFactory.getProxy(classLoader);
}
我们看一下attribute的内部结构
buildAdvisors()构建通知
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// 解析全部的拦截器
Advisor[] commonInterceptors = this.resolveInterceptorNames();
List
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 通过判断选择创建JDKAOP代理还是CglibAop代理
/**
选择的原则如下:
optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非完全了解AOP代理是如何优化,否则不推荐用户使用这个设置,目前这个属性仅用于CGLIB代理,对于JDK动态代理(缺省代理)无效。
proxyTargetClass:这个属性为true时,目标类本身被代理而不是目标类的接口。如果这个属性值被设为true,CGLIB代理将被创建
hasNoUserSuppliedProxyInterfaces 是否存在代理接口
**/
if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
// 最后或返回AopProxy类型的对象,AopProxy是一个接口,跟据选择动态代理的方式不同,会创建不同的代理对象
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
总结:JDK与Cglib动态代理的选择
proxyTargetClass true 目标对象实现了接口 – 使用CGLIB代理机制 目标对象没有接口(只有实现类) – 使用CGLIB代理机制 false 目标对象实现了接口 – 使用JDK动态代理机制(代理所有实现了的接口) 目标对象没有接口(只有实现类) – 使用CGLIB代理机制
看一下AopProxy的继承关系图
CglibAopProxy#getProxy
private Callback[] getCallbacks(Class> rootClass) throws Exception {
// 获取代理工厂中设置的一些属性信息
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 将我们自己创建的代理工厂封装成DynamicAdvisedInterceptor类型,因为DynamicAdvisedInterceptor实现了了MethodInterceptor接口,跟据Cglib动态代理的使用原理,调用cglib中的方法时会调用MethodInterceptor接口的intercept方法
Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
Object targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
} else {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), (Callback)targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
Callback[] callbacks;
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
for(int x = 0; x < methods.length; ++x) {
Method method = methods[x];
List
CglibAopProxy#getCallbacks方法
private Callback[] getCallbacks(Class> rootClass) throws Exception {
// 获取代理工厂中设置的一些属性信息
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 将我们自己创建的代理工厂封装成DynamicAdvisedInterceptor类型,因为DynamicAdvisedInterceptor实现了了MethodInterceptor接口,跟据Cglib动态代理的使用原理,调用cglib中的方法时会调用MethodInterceptor接口的intercept方法
Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
Object targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
} else {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), (Callback)targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
Callback[] callbacks;
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
for(int x = 0; x < methods.length; ++x) {
Method method = methods[x];
List
在getCallbacks中spring考虑了很多情况,但是对于我们来说,只需要理解最常用的就可以了,比如将advised属性封装在DynamicAdvisedInterceptor并加入在callbacks中,这么做的目的是什么,为什么会这么做?在前面的示例中,我们了解到CGLIB中对于方法的拦截是通过将自定义的拦截器(实现MethodInterceptor接口)加入Callback中并在调用代理的时候直接激活拦截器中的intercept方法来实现的,那么在getCallback中正是实现了这样的一个目的,DynamicAdvisedInterceptor继承自MethodInterceptor加入CallBack中后,再次调用代理时会直接调用DynamicAdvisedInterceptor中的intercept方法,所以,由此推断,对于CGLIB方式实现的代理,其核心逻辑在DynamicAdvisedInterceptor中的intercept方法,DynamicAdvisedInterceptor作为CglibAopProxy内部封装私有类,其在org.springframework.aop.framework.CglibAopProxy类中:
那我们调用代理对象的方法时,方法会被拦截,依次执行前面设置的callBack[]中的,方法拦截器的intercept(),首先会执行我们创建的封装了自定义的ProxyFactory的DynamicAdvisedInterceptor的intercept()方法,在此方法中完成我们自定义的增强逻辑。
我们看一下通知(具体的增强逻辑)的继承关系:
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取代理对象
target = targetSource.getTarget();
Class> targetClass = (target != null ? target.getClass() : null);
// 获取拦截链,我们知道我们之前给每个需要被代理对象都创建了代理工厂,代理工厂中保存了每个被代理对象能够适配(应用的)Advisor[],但是针对于特定方法,就需要从Advisor[]中选择出能够用在此方法上的Advisor增强器,并从增强器中获取具体的增强逻辑(Advice),Interceptor拦截器就是Advice的子接口,这里面获取到的就是该method能够使用的拦截器列表。
List
看一下该方法拦截器列表中的内容:
上述的实现与JDK方式实现代理中的invoke方法基本相同,都是首先构造链,然后封装此链进行串联调用,区别就是在JDK代理中直接构造ReflectiveMethodInvocation类,而在CGLIB代理中使用CglibMethodInvocation,CglibMethodInvocation继承自ReflectiveMethodInvocation,但是process方法没有重写。 JdkDynamicAopProxy#getProxy方法
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//1.为给定的AOP配置确定要代理的完整接口集
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//2.创建一个动态代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
JDKProxy的使用关键是创建自定义的InvocationHandler,而InvocationHandler中包含了需要覆盖的函数getProxy,并且JdkDynamicAopProxy还实现了InvocationHandler接口,所以,AOP的代理会调用它的invoke方法。当调用AOP 动态代理对象的方法时,就会调用它的invoke方法。
总结:
1.首先调用通过Import注册的后置处理器的..after..方法,
判断是否被代理过了,代理过了直接返回原bean
没代理过,进行代理
2.获取可用的增强器,并进行排序,排序原则如下:
/** 1.环绕增强前(around advice before) 2.前置增强(before advice) 3.-- 方法执行 4.环绕增强后(around advice after) 5.后置finally增强(after advice) 6.后置增强/抛出增强 **/
3.创建代理工厂,设置代理工厂的属性,比如目标代理对象,是否使用cglib动态代理
4.进行判断,选择创建AopProxy还是JDKProxy
5.调用代理的getProxy()方法:
设置拦截器,添加回调,创建代理对象
如有问题欢迎指正讨论.....
参考博文:参考了一篇文章,但是忘记链接是什么了.....sorry下次一定记得/(ㄒoㄒ)/~~