Aop原理:【看给容器中注册了什么组件,这个组件怎么工作的,这个组件有什么功能】
1)我们通过使用@EnableAspectJAutoProxy注解开启Aop功能
1.1实际上导入的是AspectJautoProxyRegistar
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
1.2 这个类中继承了ImportBeanDefinitionRegistrar接口,这个接口可以自定义容器中来注册Bean
public interface ImportBeanDefinitionRegistrar {
void registerBeanDefinitions(AnnotationMetadata var1, BeanDefinitionRegistry var2);
}
1.3 一开始先判断 假如容器中包含internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"))
1.4 通过创建一个Bean AnnotationAwareAspectJAutoProxyCreator
名为:internalAutoProxyCreator,注册在registry中
} else { RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", -2147483648); beanDefinition.setRole(2); registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); return beanDefinition; }
这里我们来研究一下AnnotationAwareAspectJAutoProxyCreator的继承关系
AnnotationAwareAspectJAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator
ProxyProcessorSupport 并实现了SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware接口方法(后置处理器)
2) 我们给SetBeanFactory方法,和后置处理器打上断点开始测试
3)@EnableAspectJAutoProxy会给容器中创建一个组件 AnnotationAwareAspectJAutoProxyCreate
AnnotationAwareAspectJAutoProxyCreate 是一个后置处理器
4)容器的创建流程
4.1 创建容器
利用AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext 进入创建IOC容器,进入源码
4.2 调用refresh方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
4.3 通过调用registerBeanPostProcessor注册Bean的后置处理器,拦截Bean的创建
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false)
4.4 先获取Ioc容器已经定义了需要的BeanPostProcessor(后置处理器)
通过PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)方法注册
1)先获取Ioc容器已经定义的需要创建所有BeanPostProcessor
2)给容器中添加BeanPostProcessor
3)优先注册实现了priorityOrderedPostProcessors接口的BeanPostProcessor
4)然后再来注册实现了Ordered接口的BeanPostProcessor
5)最后来实现没有优先级接口的BeanPostProcessor
看到这里,肯定很多人问注册是什么呢,这里我们来解释一下,什么叫所谓的注册
通过我箭头这个代码,我们看到了 获取到了ppname的名字internalAutoProxyCreator,看到这个有没有熟悉的感觉,就是我们上面提到的AnnotationAwareAspectJAutoProxyCreator类型
下面我们在来看看他是怎么获取到的吧
调用DogetBean,又调用getSingle(获取单实例bean)
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return this.doGetBean(name, requiredType, (Object[])null, false);
}
4.5当然我们第一次没有单实例Bean,所以我们获取的肯定会去其他方法
调用了SingletonFactory的方法,来创建一个Bean
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
创建好Bean的实例,在实例化populateBean(对于Bean的属性赋值)
try {
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
4.6 我们的后置处理器,就是在Bean的初始化前后工作的
现在我们再来看看初始化Bean的流程
调用this.invokeAwareMethods(beanName, bean)方法
判断是属于什么Bean的接口调用什么方法(处理接口回调)
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
当然我们的internalAutoProxyCreator属于BeanFactoryAware接口中的,则我们会调用setBeanFactory方法
4.7 我们现在先不进去setBeanFactory方法,先来看看执行invoke后会执行什么
我们会调用applyBeanPostProcessorsBeforeInitialization方法(应用后置处理器的Before)
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); }
其实看完就很清晰的知道,就是遍历所有Bean的后置处理器的postProcessBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator();
do {
if (!var4.hasNext()) {
return result;
}
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
} while(result != null);
return result;
}
4.8 然后执行this.invokeInitMethods(beanName, wrappedBean, mbd)(自定义初始化方法)
4.9 执行完初始化后,我们又在执行applyBeanPostProcessorsAfterInitialization
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator();
do {
if (!var4.hasNext()) {
return result;
}
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessAfterInitialization(result, beanName);
} while(result != null);
return result;
}
我们也可以发现这个跟前置通知是一样的,把所有Bean的后置处理器遍历一遍
我们在回到我们的 4.6 进去到invokeAwareMethods方法中,因为我们是BeanFactoryAware
所以调用的是SetBeanFactory方法
我们创建的是AnnotationAwareAspectJAutoProxyCreator对象,但调用的是父类的AbstractAutoProxyCreator类的setBeanFactory方法
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
} else {
this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
}
}
注意这里我们要调用initBeanFactory方法,这就会回到我们上面分析的AnnotationAwareAspectJAutoProxyCreator的初始化方法
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
成功创建aspectJAdvisorFactory,aspectJAdvisorsBuilder
把BeanPostProcessor注册到BeanFactory中
这以上就是我们创造和注册AnnotationAwareAspectJautoProxyCreator
下面我们来看看 AnnotationAwareAspectJautoProxyCreator 做了些什么
根据上面的分析,我们知道AnnotationAwareAspectJautoProxyCreator 是=》internalAutoProxyCreator 类型的处理器
在根据源码我们来探究
前面还是一样创建IOC容器
调用Refresh方法
但是第三步的时候,我们就不是调用register注册方法,而是初始化剩下的单实例bean
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
通过以下的集合和迭代器,我们也大概猜到要干吗了
没错就是遍历获取容器中的Bean,依次创建对象(getBean(beanname))
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
getBean——>dogetBean——>getsingle
下面我们来看看怎么创建Bean
1)先从缓存中获取当前Bean,如果能获取到,说明当前Bean已经被创建过
,如果不能获取,就用我们上面的getBean——>dogetBean——>getsingle方法创建Bean
2)只要创建好的Bean都会被缓存起来
.下面我们来看看创建Bean的流程
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
假如我们的是单实例的Bean,就返回AbstractBeanFactory.createBean方法中
让我们继续进去看看是怎么创建
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
如果我们的Bean能返回我们的代理对象,那就返回到beanInstance
如果不能,就调用下面的doCreateBean方法
这个doCreate方法跟我们的上面一模一样
1)创建Bean的实例
2)this.populateBean(beanName, mbd, instanceWrapper)然后populate给Bean的属性赋值
3)然后再来初始化Bean
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
4)初始化Bean的时候,要执行Aware接口
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
return null;
}
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
5)因为我们的Bean属于BeaFactoryAwre,所以执行setBeanFactory方法
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
6)然后再执行invokeAwareMethods方法前,执行后置处理器的Before
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
7)在执行前面的初始化方法
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
8)最后在执行后置处理器的After
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
整个流程就是我们上面创建Bean的流程
当然我们是已经创建过了,现在就直接进入resolveBeforeInstantiation方法中
1)后置处理器先尝试返回对象
if (targetType != null) {
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
拿到所有的后置处理器,如果后置处理器是InstantiationAwareBeanPostProcessor
如果是就执行后置处理器的postProcessBeforeInstantiation(beanClass, beanName)方法
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
这里是不是大家有个疑惑,怎么会在这里调用Before的方法呢,不是在我们前面就有调用Before后置处理器的方法呢
这是因为我们前面的是initializeBean(初始化Bean)
但这边是我们的InstantiationAwareBeanPostProcessor后置处理器(实例化Bean)
就是我们的AnnotationAwareAspectJautoProxyCreator
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
Object postProcessBeforeInstantiation(Class<?> var1, String var2) throws BeansException;
boolean postProcessAfterInstantiation(Object var1, String var2) throws BeansException;
PropertyValues postProcessPropertyValues(PropertyValues var1, PropertyDescriptor[] var2, Object var3, String var4) throws BeansException;
}
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
Instantiation表示实例化:实例化的意思在对象还未生成,
Initialization表示初始化:初始化的意思在对象已经生成
前面我们看到的是doCreateBean,这个是在我们创建doCreateBean之前调用,希望返回用后置处理器返回对象
if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
说明这个AnnotationAwareAspectJautoProxyCreator 会在任何Bean创建之前,会有一个拦截器
都会去调用postProcessBeforeInstantiation方法,尝试返回一个对象
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if (beanName == null || !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;
}
}
接下来我们来看看postProcessBeforeInstantiation这个方法做了什么事情(前置)
当然现在我们没有处理过这些Bean当然不在其中(增强器)
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
然后我们在判断是不是会基础类型的Bean和是不是基础类型的切面或者有加@Aspect注解
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && this.logger.isTraceEnabled()) {
this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
在下来判断是否需要跳过(shouldskip)
先来获取到我们的增强器(切面的通知方法)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
我们的增强器是InstantiationModelAwarePointcutAdvisor
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
判断我们的增强器是不是AspectJPointcutAdvisor类型
所以我们直接跳过这边返回false
调用完前面的postProcessBeforeInstantiation
现在我们来创建下一个对象postProcessAfterInitialization
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;
}
这里最重要的方法就是wrapIfNecessary (包装)
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
这一段又是跟前面一样判断是不是基础类型或者前面,还有是否要跳过
// Create proxy if we have advice.
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;
}
1)先来获取到当前Bean的所有增强器(通知方法)
就是我们切面定义的四个通知方法,可以应用的增强 器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
先把四个通知放到一个集合里面
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
调用AOP工具类里面的找到所有的通知方法
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
在Aop工具中,先判断每一个增强器是不是为candidateAdvisors类型的
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
这边又来判断我们增强器是不是IntroductionAdvisor类型的
在判断是否能用canApply(candidate, clazz, hasIntroductions)
当然我们这四个方法都是能用的
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
把这四个能用的方法都加载到eligibleAdvisor
找到所有增强器后,对所有增强器进行了一个排序(调用通知方法的顺序)
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
然后把这些排序好的增强器放在 Object[] specificInterceptors数组里
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;
}
保存当前Bean在adviseBean中,表示已经被增强处理
如果当前Bean需要增强,需要创建当前Bean的代理对象
下面我们来看一下代理对象创建Bean的过程
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
1)还是获取所有增强器的Bean(通知方法)
2)保存到proxyFactory中(代理工厂)
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
创建Aop代理对象
一共会有二种形式的代理对象
一个是JDK 动态代理
一个是Cglib 动态代理
mathCaluator.div
目标方法执行:
1)这个wrap方法我们调用完了,最终我们给容器中返回了当前组件使用的Cligb增强的代理对象
2)调用AopUtils工具中的intercept方法
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
3)获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
4)如果没有拦截器链,直接执行目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
5)如果有拦截器链,把拦截器链,执行目标方法的对象,目标方法等所有信息
并调用proceed方法
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
我们来看看proceed方法流程
1)创建一个List interceptorlist集合,保存所有拦截器
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
2)一共有5个,一个默认ExposeInvocationInterceptor.ADVISOR的和四个增强器
3)遍历所有的增强器,将其转为interceptors
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
将转换器转为List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
MethodInterceptor那就直接添加到集合中
如果不是AdvisorAdapte(增强器适配器),将增强器转为MethodInterceptor
转换完成后,返回并添加到集合中
//断点public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
我们来在我们上面打上断点后开始测试,先跳过默认的从第二个开始
1)现在进来的是我们的LogException方法(异常方法)
判断是不是MethodInterceptor接口,返回的是true,说明是这个接口,直接添加进集合中去
2)现在进来的是我们的LogReturn方法
判断是不是MethodInterceptor接口,返回的是false,则进入下面的方法
这底下有三个AdvisorAdapter(增强适配器)
第一个先来调用我们的MethodBefore方法,发现不是
又来调用我们的AfterReturnning的方法
因为我们的LogReturn属于supportAdvice中
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
3)第三个进来的为logEnd方法
LogEnd属于MethodInterceptor方法中,所以直接被添加到集合中
4)第四个进来的为logStart方法
判断是不是MethodInterceptor接口,返回的是false,则进入下面的方法
第一个先来调用我们的MethodBefore方法,发现是属于这个方法中
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
我们进去看这个方法发现,其实就是直接给这个方法包装一个Interceptor而已
然后就添加到集合中
我们发现已经把全部增强器转换为MethodInterceptor(方法拦截器)
拦截器链(每一个通知方法又被包装成方法拦截器,利用MethodInterceptor机制)
比如通过@EnablAspectJAutoProxy创建的internalAutoProxyCreator
通过finishBeanFactoryInitialization方法创建其他所有的单实例Bean
创建业务逻辑组件和切面组件(@Before,@After,@AfterReturning,@AfterThrowing)
六——执行目标方法
Cglib.intercept会得到目标方法的拦截器链(增强器Advisor)
利用拦截器的链式机制依次进入每一个拦截器,进行执行
根据栈的方式,先进后出
如果是Spring4
正常执行:前置通知——>目标方法——>后置通知——>返回通知
异常执行 前置通知——>目标方法——>后置通知——>异常通知
Spring5
正常执行:前置通知——>目标方法——>返回通知——>后置通知
异常执行 前置通知——>目标方法——>异常通知——>后置通知