面向对象编程有一些弊端,就是需要多个不具有继承关系的对象引入同一个公共行为时,需要在每个对象里引入公共行为,在程序中产生了大量的重复代码,所以有了面向切面编程(AOP)
1使用动态AOP
1.1创建测试方法
public class TestBean {
private String testStr = "testStr";
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
public void test() {
System.out.println(this.testStr);
}
}
1.2创建Advisor(增强器)
@Aspect
public class AspectJTest {
@Pointcut("execution(public * com.zero.bean..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void beforeTest() {
System.out.println("Before before");
}
@After("webLog()")
public void afterTest() {
System.out.println("After after");
}
@Around("webLog()")
public Object aroundTest(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("Around before");
Object object = null;
try {
object = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("Around after");
return object;
}
}
1.3创建配置文件
新建配置文件aspect.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--在配置文件中声明了这句配置,Spring就会支持注解AOP-->
<aop:aspectj-autoproxy/>
<bean id="test" class="com.zero.bean.TestBean"/>
<bean class="com.zero.aspect.AspectJTest"/>
</beans>
1.4创建测试方法
ApplicationContext beans = new ClassPathXmlApplicationContext("aspect.xml");
TestBean testBean = (TestBean) beans.getBean("test");
testBean.test();
1.5测试结果
Around before
Before before
testStr
Around after
After after
2动态AOP自定义标签
之前讲过Spring的自定义注解,如果声明了自定义注解,就会有对应的解析器,而AOP标签的解析器就是AspectJAutoProxyBeanDefinitionParser,在解析配置文件的时候,一旦遇到aspectj-autoproxy注解,就会使用定义的对应解析器进行解析
package org.springframework.aop.config;
public class AopNamespaceHandler extends NamespaceHandlerSupport {
/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
2.1注册AnnotationAwareAspectJAutoProxyCreator
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
AnnotationAwareAspectJAutoProxyCreator继承了BeanPostProcessor接口,继承了这个接口,Spring会在实例化Bean前调用
所有解析器都是对BeanDefinitionParser接口的统一实现,入口都是从parse函数开始的,AspectJAutoProxyBeanDefinitionParser的parse函数如下:
package org.springframework.aop.config;
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册AnnotationAwareAspectJAutoProxyCreator
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//对于注解中子类的处理
extendBeanDefinition(element, parserContext);
return null;
}
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
package org.springframework.aop.config;
public abstract class AopNamespaceUtils {
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//注册或升级AutoProxyCreator定义beanName为org.Springframework.aop.config.internalAutoProxyCreator的BeanDefinition
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//对于proxy-target-class以及expose-proxy属性的处理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册组件并通知,便于监听器进一步处理
//其中beanDefinition的className为AnnotationAwareAspectJAutoProxyCreator
registerComponentIfNecessary(beanDefinition, parserContext);
}
2.1.1注册或升级AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
对于AOP的实现,基本是靠AnnotationAwareAspectJAutoProxyCreator去完成,它可以根据@Point注解定义的切点来自动代理相匹配的bean,但是为了配置简便,Sprig使用了自定义配置来帮助我们自动注册AnnotationAwareAspectJAutoProxyCreator,其注册过程就是在这里实现
AnnotationAwareAspectJAutoProxyCreator继承自ProxyProcessorSupport
package org.springframework.aop.config;
public abstract class AopConfigUtils {
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果已经存在了自动代理创建器且存在的自动代理创建器与现在的不一致那么需要根据优先级来判断到底用哪个
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
//改变bean最重要的就是改变bean对应的className属性
apcDefinition.setBeanClassName(cls.getName());
}
}
//如果已经存在自动代理创建器并且与将要创建的一致,那么无需再次创建
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//Ordered.HIGHEST_PRECEDENCE 最高优先级 Integer.MIN_VALUE
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
以上代码中实现了自动注册AnnotationAwareAspectJAutoProxyCreator类的功能,这里还涉及优先级的问题,如果已经存在自动代理创建器,而且存在的自动代理创建器与现在的不一致,那么需要根据优先级判断到底需要使用哪个
2.1.2处理proxy-target-class以及expose-proxy属性
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
userClassProxyingIfNecessary实现了proxy-target-class属性以及expose-prosy属性的处理
proxy-target-class
Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理(建议尽量使用JDK的动态代理),如果被代理的目标对象至少实现了一个接口,则使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。如果希望使用CGLIB代理,需姚考虑两个问题
- 无法通知(advise)Final方法,因为不能被覆写
- 需要将CGLIB二进制包放在classpath下
JDK本身提供了动态代理,强制使用CGLIB代理需要将<<aop:config>>的proxy-target-class属性设置为true:
<aop:aspectj-autoproxy proxy-target-class="true">...</aop:config>
当需要使用CGLIB代理和@AspectJ自动代理支持,可以按照以下方式设置<<aop:aspecctj-autoproxy>>的proxy-target-class属性:
<aop:aspect-autoproxy proxy-target-class="true"/>
- JDK动态代理:代理对象必须是某个接口的实现,通过在运行期间创建一个接口的实现类来完成对目标对象的代理
- CGLIB代理:实现原理类似于JDK动态代理,只是在运行期间生成的代理对象是针对目标类扩展的子类.CGLIB是高效的代码生成包,底层依靠ASM(开源的JAVA字节码编辑类库)操作字节码实现,性能比JDK强
expose-prosy
有时候目标对象内部的自我调用无法实施切面中的增强
public interface UserService{
public void a();
public void a();
}
public class UserServiceImpl implements UserService{
@Transactional(propagation = Propagation.REQUIRED)
public void a(){
this.b();
}
@Transactional(propagation = Propagation.REQUIRED_NEW)
public void b(){
System.out.println("b has been called");
}
}
此处this指向目标对象,因此调用this.b()将不会指向b的事务切面,即不会执行事务增强,因此b方法的事务定义@Transactional(propagation = Propagation.REQUIRED)将不会实施,为解决此问题可以配置
<aop:aspectj-autoproxy expose-proxy=“true”>
将代理暴露出来使用,AopContext.currentProxy()获取当前代理,将this.b()改为((UserService)AopContext.currentProxy()).b(),即可以完成对a和b两个方法的同时增强
package org.springframework.aop.config;
public abstract class AopNamespaceUtils {
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
//对于proxy-target-class属性的处理
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//对于expose-proxy属性的处理
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
3创建AOP代理
上文中讲解了通过自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类到底做了什么工作来完成AOP操作呢?
在AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,而实现BeanPostProcessor后会在Bean实例化前和初始化前后执行postProcessBeforeInitialization和postProcessAfterInitialization方法
3.1创建Bean
我们来说分析AOP的逻辑,发现首先加载了一个Bean org.springframework.aop.config.internalAutoProxyCreator,第二次才是加载要创建的Bean test,在第二次加载时会在执行方法之前执行resolveBeforeInstantiation方法,给BeanPostProcessors一个机会来返回代理来替代真正的实例
3.1.1创建Bean操作 createBean
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 确保此时确实解析了bean类,并且
// 在动态解析的类的情况下克隆bean定义
// 无法存储在共享的合并bean定义中。
// 反射解析bean类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//验证及准备覆盖的方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给BeanPostProcessors一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//短路判断,如果经过前置处理后的返回结果不为空,会直接忽略后续的bean而直接返回,AOP就是基于这里判断的
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
3.1.2实例化Bean的前置处理resolveBeforeInstantiation
当Spring加载这个Bean时会在实例化Bean的前置处理中(resolveBeforeInstantiationn)调用其postProcessBeforeInstantiation和postProcessAfterInitialization方法,在applyBeanPostProcessorsBeforeInstantiation中如果定义了TargetSource就会返回代理,然后执行postProcessAfterInitialization并直接返回。
3.1.2.1实例化前的解析resolveBeforeInstantiation
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the shortcut-determined bean instance, or {@code null} if none
* 应用实例化后处理器,以解决是否存在
* 指定bean的实例化前快捷方式。
* @param beanName bean的名称
* @param mbd bean的bean定义
* @返回快捷方式确定的bean实例;如果没有,则返回{@code null}
*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//如果未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化bean前的前置操作,如果存在代理就返回代理,如果没有配置targetSource会返回null,下面就不会执行,AOP的操作会到初始化bean后再执行
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//创建bean前的后置操作,前置操作的返回结果不为空,则后置继续处理,否则就没有代理,直接返回bean
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//获取所有实现BeanPostProcessor的对象,AOP的AnnotationAwareAspectJAutoProxyCreator也实现了BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//bp是AOP注册的,符合条件,所以执行postProcessBeforeInstantiation
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
//如果TargetSource不为空,则直接返回null
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
3.1.2.2执行实例化前的操作postProcessBeforeInstantiation
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
在执行Bean开始实例化之前,判断是否存在targetSource,如果存在,就对bean进行代理并返回,由于配置了短路判断,如果此时返回的对象不为空,就直接返回这个对象作为bean
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;
}
}
package org.springframework.aop.framework.autoproxy;
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//如果存在增强方法就创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
3.1.3创建bean doCreateBean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
具体操作见第四篇文档,这里主要说和AOP相关的部分
在初始化(initializeBean)前后也会执行postProcessBeforeInstantiation和postProcessAfterInitialization方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
3.1.3.1初始化bean的前置处理 applyBeanPostProcessorsBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
BeanPostProcessor给用户充足的权限去更改或者扩展Spring
3.1.3.1.1执行初始化的前置处理applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
3.1.3.1.2初始化的前置处理postProcessBeforeInitialization
invokeAwareInterfaces每次Bean加载前都会执行
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
3.1.3.2初始化bean的后置处理applyBeanPostProcessorsAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
在后置处理结束后,返回代理过的对象,我们可以看到,对象已经成为了CGLIB代理对象
3.1.3.2.1执行初始化的后置处理applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//获取所有实现BeanPostProcessor的对象,AOP的AnnotationAwareAspectJAutoProxyCreator也实现了BeanPostProcessor
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
3.1.3.2.2初始化的后置处理postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//根据指定的bean的class和name构建出key,格式beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
3.1.3.2.3封装并创建代理wrapIfNecessary
package org.springframework.aop.framework.autoproxy;
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
* 必要时包装给定的bean,即是否有资格被代理。
* @param bean原始bean实例
* @param beanName bean的名称
* @param cacheKey用于元数据访问的缓存键
* @返回一个包装该bean的代理,或者按原样返回裸bean实例
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经处理过
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//缓存中valud为false,如果缓存中不存在就是null,会继续向下执行,存在才有true/false,如果是不需要增强的就是false,需要增强的就是true
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//给定的bean类是否代表一个基础设施类,基础设施类不应该代理,或者配置了指定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);// 获取所有的增强,并寻找所有增强中适用于bean的增强并应用
if (specificInterceptors != DO_NOT_PROXY) {// protected static final Object[] DO_NOT_PROXY = null; 获取到的增强器数组不为空,就针对增强创建代理
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;
}
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
/**
* Find all eligible Advisors for auto-proxying this class.
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。