一、简介
aop(面向切面编程)是对oop(面向对象编程)的补充和完善。它是利用一种被称为“横切”的技术,解剖开封装的对象的内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并命名为“Aspect”,即切面。所谓的切面,简单的说就是那些与业务无关,却为业务模块所共同调用的逻辑代码封装起来,便于减少系统的重复代码,降低代码之间的耦合,并有利于未来的可操作性和可维护性。
aop的核心概念
1、横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
2、切面(Aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象
3、连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
4、切入点(pointcut):对连接点进行拦截的定义
5、通知(advice):通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
6、目标对象:代理的目标对象
7、织入(weave):将切面应用到目标对象并导致代理对象构建的过程
8、引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
二、实现原理
Spring中aop代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,aop代理可以直接使用容器中的其他bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则是:
1、默认使用java动态代理来创建aop代理,这样就可以为任何接口实例创建代理了。
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可以强制使用CGLIB。
创建aop对象实例是从refresh()方法中的registerBeanPostProcessors()方法为入口。但是在这之前也已经向容器中注入了AnnotationAwareAspectJAutoProxyCreator。
通过代码实例来解释说明AOP的原理和类之间的关系。
配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class MainConfig {
@Bean
Calculate calculate() {
return new MyCalculate();
}
@Bean
MyLogAspect myLogAspect() {
return new MyLogAspect();
}
}
正在上面的配置类中看到增加可EnableAspectJAutoProxy注解,进入这个注解的源码,我们可以看到这个注解引入了AspectJAutoProxyRegistrar类。这个类主要的作用是根据给定的EnableAspectJAutoProxy注释,适当地针对当前BeanDefinitionRegistry注册一个AnnotationAwareAspectJAutoProxyCreator。主要是为了完成AnnotationAwareAspectJAutoProxyCreator的注册,这个类的主要作用是aop切面代理创建。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册AnnotationAwareAspectJAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
定义一个计算接口类作为模板类。
package com.spring.source.aop;
/**
* 计算类接口
* Created by lenovo on 2019/7/1.
*/
public interface Calculate {
/**
* 加法
* @param numA
* @param numB
* @return
*/
int add(int numA,int numB);
/**
* 减法
* @param numA
* @param numB
* @return
*/
int reduce(int numA,int numB);
/**
* 乘法
* @param numA
* @param numB
* @return
*/
int multi(int numA,int numB);
/**
* 除法
* @param numA
* @param numB
* @return
*/
int div(int numA,int numB);
/**
* 取模
* @param numA
* @param numB
* @return
*/
int mod(int numA,int num
实现此接口的类
package com.spring.source.aop;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
/**
* Created by lenovo on 2019/7/1.
*/
public class MyCalculate implements Calculate {
@Override
public int add(int numA, int numB) {
System.out.println("执行目标方法:add");
return numA + numB;
}
@Override
public int reduce(int numA, int numB) {
System.out.println("执行目标方法:reduce");
return numA - numB;
}
@Override
public int multi(int numA, int numB) {
System.out.println("执行目标方法:multi");
return numA * numB;
}
@Override
public int div(int numA, int numB) {
System.out.println("执行目标方法:div");
return numA / numB;
}
@Override
public int mod(int numA, int numB) {
System.out.println("执行目标方法:mod");
int retVal = ((Calculate)AopContext.currentProxy()).add(numA, numB);
// int retVal = this.add(numA, numB);
// return retVal%numA;
return numA % numB;
还定义了一个aop切面的实现类
package com.spring.source.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* Created by lenovo on 2019/7/1.
*/
@Aspect
public class MyLogAspect {
@Pointcut("execution(* com.spring.source.aop.MyCalculate.*(..))")
public void pointCut(){}
@Before(value = "pointCut()")
public void methodBefore(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行目标方法["+methodName+"]之前执行<前置通知>,入参" + Arrays.asList(joinPoint.getArgs()));
}
@After(value = "pointCut()")
public void methodAfter(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行目标方法["+methodName+"]之前执行<后置通知>,入参" + Arrays.asList(joinPoint.getArgs()));
}
@AfterReturning(value = "pointCut()")
public void methodReturn(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行目标方法["+methodName+"]之前执行<返回通知>,入参" + Arrays.asList(joinPoint.getArgs()));
}
@AfterThrowing(value = "pointCut()")
public void methodAfterThrowing(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行目标方法["+methodName+"]之前执行<异常通知>,入参" + Arrays.asList(joinPoint.getArgs()));
}
@Around(value = "pointCut()")
public Object methodAround(ProceedingJoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println(joinPoint.getTarget().getClass().getName());
System.out.println(joinPoint.getSignature().getClass().getName());
System.out.println("执行目标方法["+methodName+"]之前执行<环绕通知>,入参" + Arrays.asList(joinPoint.getArgs()));
//调用目标方法
Object sum = null;
try {
sum = joinPoint.proceed(joinPoint.getArgs());
} catch (Throwable throwable) {
System.out.println("调用目标方法异常:"+throwable.getMessage());
throwable.printStackTrace();
}
return sum;
根据上面的实例代码,画出AOP的源代码流程图。
前面的容器初始化,加载配置、后置处理器前面已经详细的介绍过,这里就不再详细的赘述。
理解AOP先从EnableAspectJAutoProxy注解说起,先看EnableAspectJAutoProxy注解。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//是否启用CGLIB动态代理,默认使用JDK代理
boolean proxyTargetClass() default false;
//是否向外暴漏动态代理的对象
boolean exposeProxy() default false;
在EnableAspectJAutoProxy注解上导入了AspectJAutoProxyRegistrar类,这个类是实现了ImportBeanDefinitionRegistrar接口,凡是实现了这个接口的类都可以给我们的容器中添加bean定义。这个类的作用是往容器中注册了一个名称为org.springframework.aop.config.internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator的注解Aspectj自动代理创建器。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
// 注册 ,增强,配置切面自动代理创建器
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//往容器中注册对应的aspectj注解自动代理创建器 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
//注册一个AnnotationAwareAspectJAutoProxyCreator(注解适配的切面自动创建器)
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator 名称的bean定义
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) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//容器中没有 那么就注册一个名称叫org.springframework.aop.config.internalAutoProxyCreator 类型是AnnotationAwareAspectJAutoProxyCreator的bean定义
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);
2、现在分析AnnotationAwareAspectJAutoProxyCreator,先看此类的继承关系
AnnotationAwareAspectJAutoProxyCreator是实现了BeanFactoryAware接口。AbstractAutoProxyCreator实现了BeanFactoryAware接口,AbstractAutoProxyCreator类的setBeanFactory()方法没有做什么,但是子类AbstractAdvisorAutoProxyCreator覆盖了这个方法。
public void setBeanFactory(BeanFactory beanFactory) {
//调用父类方法
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
//初始化bean工厂方法
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
AnnotationAwareAspectJAutoProxyCreator类覆盖了initBeanFactory()方法,
//创建一个AOP的增强器通过@ApesctJ注解的方式
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//调用父类的方法
super.initBeanFactory(beanFactory);
//若aspectj的增强器工厂对象为空,就创建一个ReflectiveAspectJAdvisorFactory
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
//不为空,就把AspectJAdvisorFactory包装为BeanFactoryAspectJAdvisorsBuilderAdapter
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware,做了两件事情:
(1)、把BeanFactory保存到AnnotationAwareAspectJAutoProxyCreator组件上
(2)、为AnnotationAwareAspectJAutoProxyCreator的aspectJAdvisorsBuilder aspect增强器赋值。
AnnotationAwareAspectJAutoProxyCreator还实现了BeanPostProcessor接口(后置处理器特性)
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
//这个方法很重要,创建真正的代理对象
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//包装bean,真正的创建代理对象逻辑
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
refresh()方法中的finishBeanFactoryInitialization()方法开始。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化此上下文服务.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//如果没有bean的后置处理器,注册一个默认的嵌入的解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
//允许缓存所有bean定义,不期待进一步的变化
beanFactory.freezeConfiguration();
//初始化所有非懒加载剩余的单例
beanFactory.preInstantiateSingletons
加载所有的剩余非懒加载的单例
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取缓存中beanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//触发所有非懒加载初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//获取bean
getBean(beanName);
}
}
}
//触发所有可以使用bean的后置初始化回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
AbstractBeanFactory类中获取bean的方法getBean()
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
@Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent.
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName
AbstractAutowireCapableBeanFactory类的createBean()方法,创建一个bean实例
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//确认bean的类在此时已经被解析,并且复制那些不能保存在共享的bean定义
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//给bean的后置处理器一个机会,返回目标bean实例的代理
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
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.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
AbstractAutowireCapableBeanFactory类的resolveBeforeInstantiation()方法应用实例化前后置处理器,解析是否有实例化前快捷方式的指定bean。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//确认bean类在此处真正被解析过
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化前的后置处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//实例化后的后置处理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
AbstractAutowireCapableBeanFactory类的applyBeanPostProcessorsBeforeInstantiation()方法把InstantiationAwareBeanPostProcessors处理器应用到制定的bean定义上,激活他们的postProcessBeforeInstantiation方法。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断容器中是否有InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
AbstractAutoProxyCreator类的postProcessBeforeInstantiation()方法,实例化之前进行后置处理
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
//判断TargetSource缓存中是否包含当前bean,如果不包含,则判断当前的bean是否是已经被代理的bean,如果代理过,则不对当前传入的bean进行处理,如果没有代理过,则判断当前bean是否为系统bean,或者是切面逻辑不会包含的bean,如果是,则将当前bean缓存到advisedBeans中,否则继续往下执行。经过这一步的处理之后,只有在TargetSource中没有进行缓存,并且应该被切面逻辑环绕,但是目前还未生成代理对象的bean才会通过此方法
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//若是基础的class||是否应该跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
//把cacheKey存放在advisedBeans中
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 获取封装当前bean的TargetSource对象,如果不存在,则直接退出当前方法;否则从TargetSource中获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//获取能够对当前bean应用的通知和增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//根据切面逻辑生成当前bean的代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
AbstractAutoProxyCreator类的isInfrastructureClass()方法,返回给定的bean类是否表示永远不应该代理的基础设置类。默认将实现advice、advisor和AopInfrastructureBeans作为基础设施类。
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 && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
AspectJAwareAdvisorAutoProxyCreator类的shouldSkip()方法,如果这个后处理器考虑使用给定的bean进行自动代理,则子类应该覆盖此方法并返回true。
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
//通过缓存的切面名称列表,进行优化
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
AnnotationAwareAspectJAutoProxyCreator类的findCandidateAdvisors()方法,找出候选的增强器。
protected List<Advisor> findCandidateAdvisors() {
// 根据父类规则找到所有的用于动态代理的增强器
List<Advisor> advisors = super.findCandidateAdvisors();
//在bean工厂中为所有的AspectJ切面构建增强器
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
BeanFactoryAspectJAdvisorsBuilder类的buildAspectJAdvisors()方法,在bean工程中找到所有的AspectJ注解切面,并且把切面转化为增强器。此方法第一步先从增强器缓存中获取增强器对象,判断缓存中有没有增强器对象,如果有,那么直接从缓存中获取然后返回。如果没有,从容器中获取所有的beanName,遍历上一步获取所有的beanName,通过beanName获取beanType,根据beanType判断当前bean是否是一个AspectJ注解类,若不是不做任何处理。
public List<Advisor> buildAspectJAdvisors() {
//现从缓存中获取
List<String> aspectNames = this.aspectBeanNames;
//获取中没有获取到
if (aspectNames == null) {
synchronized (this) {
//再次尝试从缓存中获取一次
aspectNames = this.aspectBeanNames;
//还是没有获取到
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//从容器中获取所有bean的name
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历beanNames
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 根据beanName获取bean的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
检查beanType是否包含Aspectj
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
//创建一个AspectJ类的源信息对象
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//根据bean工厂和bean name创建BeanFactoryAspectInstanceFactory
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//从有Aspectj注解的类中获取通知器
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
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();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
// 调用advisorFactory.getAdvisors获取通知器
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
ReflectiveAspectJAdvisorFactory类中getAdvisors()方法获取增强器。
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取标识了AspectJ注解的切面类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取切面的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// 包装MetadataAwareAspectInstanceFactory
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//获取所有切面类中所有通知方法,除了Pointcut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
//获取方法的增强器
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors
ReflectiveAspectJAdvisorFactory类的getAdvisor()方法获取具体的增强器。
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取aspectj的切点表达式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//创建advisor实现类
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
通过InstantiationModelAwarePointcutAdvisorImpl的构造方法创建Advisor的实现类。
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
//使其成为动态的,必须从预实例化状态改变为后置实例化状态
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
this.pointcut = this.declaredPointcut;
this.lazy = false;
//实例化增强器
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
InstantiationModelAwarePointcutAdvisorImpl类的instantiateAdvice()方法中调用了ReflectiveAspectJAdvisorFactory类中的getAdvice()方法切面对象和增强器。
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取候选的切面类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//获取切面注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
//判断注解类型
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut://是切点返回null
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround://环绕通知
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore://前置通知
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter://后置通知
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning://返回通知
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing://异常通知
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
//配置通知
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
//获取方法的参数列表
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
//为切面设置参数
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice
至此把aop相关的通知,增强器等都注入到了容器中,并且有的已经创建了代理。如果没有创建代理,在调用对用方法的时候也会创建代理,下一小节中具体分析实现的源代码。
三、小结
aop注入容器,创建代理的过程。