一、前提
本片文章会从源码角度介绍aop的原理;共分为5个小节,每个小节后会有总结;想直接看结果的可直接关注小结内容或这节关注最后的总结;如有理解有误,欢迎指教
二、从一个简单的aop例子说起
1、定义一个切面,切入点为MathCalculator类里的所有方法;
@Aspect
public class LogAspects {
//抽取公共的切入点表达式
@Pointcut("execution(public int com.aop.MathCalculator.*(..))")
public void pointCut(){};
//@Before在目标方法之前切入
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
}
//@Before在目标方法之后切入
@After("com.aop.LogAspects.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
}
//在目标方法(div)正常返回之后运行
//JoinPoint一定要出现在参数表的第一位,否则会出现参数匹配异常
@AfterReturning(value="pointCut()",returning="result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
}
//在目标方法(div)出现异常以后运行
@AfterThrowing(value="pointCut()",throwing="exception")
public void logException(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
}
}
2、定义目标类MathCalculator;
public class MathCalculator {
public int div(int i,int j){
System.out.println("MathCalculator...div...");
return i/j;
}
}
3、定义配置类,@EnableAspectJAutoProxy表示开启事务
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
//业务逻辑类加入容器中
@Bean
public MathCalculator calculator(){
return new MathCalculator();
}
//切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
4、测试类
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(1, 0);
}
5、输出结果:
div运行。。。@Before:参数列表是:{[1, 0]}
MathCalculator...div...
div结束。。。@After
div异常。。。异常信息:{java.lang.ArithmeticException: / by zero}
java.lang.ArithmeticException: / by zero
可见,当执行到目标方法mathCalculator.div()时,会先执行前置通知-》目标方法-》后置通知-》异常通知
三、原理
1、@EnableAspectJAutoProxy注解作用
由上面的例子可见,aop实现依赖于这个注解@EnableAspectJAutoProxy,我们打开这个注解看一下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
EnableAspectJAutoProxy中使用@import快速导入AspectJAutoProxyRegistrar,打开AspectJAutoProxyRegistrar看一下:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
重点为AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)
这行代码(下面的两个if判断不会走,注解@EnableAspectJAutoProxy里proxyTargetClass与exposeProxy两个属性默认false),跟进去如下:
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
上面代码主要是将AnnotationAwareAspectJAutoProxyCreator这个组件包装成beanDefinition然后注册到BeanDefinitionRegistry中;来捋一下AnnotationAwareAspectJAutoProxyCreator这个组件的继承关系:
AnnotationAwareAspectJAutoProxyCreator:
AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
SmartInstantiationAwareBeanPostProcessor是一个后置处理器BeanPostProcessor,这里现记载下来,后面会用到这个 BeanPostProcessor
小结:
1. @EnableAspectJAutoProxy注解利用@Import(AspectJAutoProxyRegistrar.class)给容器中导入AspectJAutoProxyRegistrar
2. 利用AspectJAutoProxyRegistrar自定义给容器中注册bean
3. 注册的bean为internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator(后置处理器)
2、refresh刷新容器
容器启动会加载所有的单实例bean以及需要aop增强的类;容器启动最核心的方法为refresh方法:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
resetCommonCaches();
}
}
}
3、AnnotationAwareAspectJAutoProxyCreator创建过程
上节说到@EnableAspectJAutoProxy会给容器中导入一个组件叫AnnotationAwareAspectJAutoProxyCreator;AnnotationAwareAspectJAutoProxyCreator实质是一个BeanPostProcessors,而容器初始化的时候会创建这个组件,具体在registerBeanPostProcessors(beanFactory)方法创建,registerBeanPostProcessors作用为注册bean的后置处理器,拦截bean的创建,截取下主要代码:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1、获取所有的BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 2、给容器中添加一个BeanPostProcessor
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//3、定义各种BeanPostProcessor分类集合
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
//4、遍历所有的BeanPostProcessor,按类型将其装入各自的集合
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//5、从beanFactory工厂获取BeanPostProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//添加priorityOrdered类型的PostProcessors
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//添加internal类型的PostProcessors
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//添加ordered类型的PostProcessors
orderedPostProcessorNames.add(ppName);
}
else {
//添加其他类型的PostProcessors
nonOrderedPostProcessorNames.add(ppName);
}
}
...省略
}
上面主要逻辑为获取所有的BeanPostProcessor,再给容器添加一个BeanPostProcessor,遍历BeanPostProcessor,按类型将BeanPostProcessor加入对应的集合中;核心在于beanFactory.getBean中如何获取bean,实则为创建BeanPostProcessor对象,然后保存在容器中;getBean方法如下:
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
doGetBean主要方法如下:
// 创建一个单事例Bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
createBean主要逻辑:
try {
// 创建代理类
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);
}
// 创建bean实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
resolveBeforeInstantiation(beanName, mbdToUse)方法是返回一个代理类的,需要aop增强的bean会被代理;我们这里是创建BeanPostProcessor,是不需要被代理的,所以会走下面的doCreateBean(beanName, mbdToUse, args)方法,真正的去创建一个bean;
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建bean 反射调用构造方法
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 给bean里的属性赋值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 调用bean的初始化之类的方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
来看一下重点步骤:
1、createBeanInstance(beanName, mbd, args)这里是真正的创建bean,里面是利用反射调用的构造方法,然后将bean初始化后包装成BeanWrapper,这里不是aop的重点,不做详细介绍
2、populateBean(beanName, mbd, instanceWrapper)这是给bean里的属性赋值(比如@Autowired以来的属性)
3、initializeBean(beanName, exposedObject, mbd)调用bean的初始化方法,什么是初始化方法?initializeBean方法主要逻辑如下?
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 给Aware接口实现类的属性赋值
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;
}
1、invokeAwareMethods():处理Aware接口的方法回调;比如实现XXXaware接口,就可以拿到对映的属性;参考ApplicationContextAware
2、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
3、invokeInitMethods();执行自定义的初始化方法,也就是调用afterPropertiesSet方法(需要实现InitializingBean接口)
4、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
至此、AnnotationAwareAspectJAutoProxyCreator组件创建完毕;
小结:
1、创建ioc容器,调用refresh()刷新容器
2、执行registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建
2.1、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
2.2、给容器中加别的BeanPostProcessor
2.3、优先注册实现了PriorityOrdered接口的BeanPostProcessor
2.4、再给容器中注册实现了Ordered接口的BeanPostProcessor
2.5、注册没实现优先级接口的BeanPostProcessor
2.6注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中【AnnotationAwareAspectJAutoProxyCreator】
2.6.1、创建Bean的实例
2.6.2、populateBean;给bean的各种属性赋值
2.6.3、initializeBean:初始化bean
2.6.3.1、invokeAwareMethods():处理Aware接口的方法回调
2.6.3.2、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
2.6.3.3、invokeInitMethods();执行自定义的初始化方法
2.6.3.4、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
2.6.4、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功
2.7、把BeanPostProcessor注册到BeanFactory中;
4、finishBeanFactoryInitialization创建剩下的单实例bean
在上一小节2中,ioc容器在registerBeanPostProcessors方法创建了所有的BeanPostProcessors,其中就包含AnnotationAwareAspectJAutoProxyCreator这个组件;这个组件的作用是拦截所有的bean创建,在bean创建之前判断该bean是否需要代理,如果需要,则创建代理对象;反正去真正的创建bean;
来看一下ioc容器初始化倒数第二部finishBeanFactoryInitialization方法,顾名思义,创建剩下的单实例bean,finishBeanFactoryInitialization如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
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));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
重点在beanFactory.preInstantiateSingletons();方法,创建所有的非懒加载的单实例bean,preInstantiateSingletons如下:
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
上诉主要逻辑为遍历获取容器中所有的Bean,依次创建对象getBean(beanName);实则为创建bean;而getBean(beanName)方法和我们上一节创建BeanPostProcessors是一样的,执行流程为getBean->doGetBean->createBean,主要看下createBean逻辑(与上一节的creteBean是一个方法)
protected Object createBean(String beanName, RootBeanDefinition mbd, 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.
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.
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);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
重点在resolveBeforeInstantiation方法,从上面的注释翻译看:“给BeanPostProcessors一个机会,一个可以返回代理类的机会”,如果能返回代理类,那么直接返回;如果不能 则调用下面doCreateBean方法真正的去创建bean实例;什么样的bean才能被代理呢!就是那些切面类、需要增强的类;
resolveBeforeInstantiation主要逻辑:
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的前置处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 应用bean的后置处理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation做了如下操作:
- 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
- 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
- 是否需要跳过
重点在applyBeanPostProcessorsAfterInitialization这,应用bean的后置处理器在bean实例化之后;来看下applyBeanPostProcessorsAfterInitialization主要逻辑:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
循环调用BeanPostProcessors子类的postProcessAfterInitialization方法;BeanPostProcessors是一个接口,具体逻辑由自类实现;前面第一节我们说到@EnableAspectJAutoProxy会像容器中导入一个组件叫AbstractAutoProxyCreato(AnnotationAwareAspectJAutoProxyCreator的父类),而这个组件也是一个后置处理器,当执行到这个组件时,就会调用AbstractAutoProxyCreator的postProcessAfterInitialization方法,点进去看一下AbstractAutoProxyCreator的postProcessAfterInitialization方法:
小结:
1、finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例bean
2、遍历获取容器中所有的Bean,依次创建对象getBean(beanName);getBean->doGetBean()
2.1、创建bean;AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截;先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;只要创建好的Bean都会被缓存起来;
2.2、createBean();创建bean;AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例
2.2.1、resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
2.2.1.1、后置处理器先尝试返回对象; bean = applyBeanPostProcessorsBeforeInstantiation():
拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;
就执行postProcessBeforeInstantiation
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
2.2.1.2、doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和BeanPostProcessors流程一样;
```java
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
可以看到postProcessAfterInitialization主要逻辑为先从缓存中获取,获取不到直接调用wrapIfNecessary,从方法名看来“如果需要的话就包装”,点进去看一下:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
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;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
前几个判断是从缓存中取,取到直接返回;再判断当前bean是否需要被代理;如果需要被代理的对象并且首次创建,前几个if不会走,直接看getAdvicesAndAdvisorsForBean方法;
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
findEligibleAdvisors(beanClass, beanName)为给当前的bean找可用的Advisors,什么意思?就是根据切入点表达式==execution(public int com.aop.MathCalculator.*(…))==来计算你当前要创建的bean是否满足该表达式;如果不满足 返回return DO_NOT_PROXY则不需要创建,反之返回增强点;增强点就是@Before、@After、@AfterReturning和@AfterThrowing方法;
如果需要被代理,则会走到这行代码:
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
createProxy方法:
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
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());
}
proxyFactory.getProxy最终会调用createAopProxy方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
如果是接口则使用jdk,否则使用cglib;至此会创建一个代理对象;(代理对象如何创建的详见这里)。
至此、ioc容器初始化完毕,所有的单实例bean和切面都创建完毕;当执行到目标方法时,实则执行的是代理类的方法,被cglib代理过的类都会进入CglibAopProxy的intercept方法;intercept方法如下:
小结:
postProcessAfterInitialization方法总结:return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
1、获取当前bean的所有增强器(通知方法)
2、保存当前bean在advisedBeans中;
3、如果当前bean需要增强,创建当前bean的代理对象;
3.1、Spring自动决定 JdkDynamicAopProxy(config);jdk动态代理; ObjenesisCglibAopProxy(config);cglib的动态代理;
4、给容器中返回当前组件使用cglib增强了的代理对象;
5、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
5、CglibAopProxy.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;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
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);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);会将增强的方法以及原目标方法保存到一个链中(List),就是@Before、@After、@AfterReturning、@AfterThrowing、@Around标注的方法;当执行到proceed()时,就会依次执行到这些方法;
6、总结
1、 @EnableAspectJAutoProxy 开启AOP功能
2、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4、容器的创建流程:
4.1、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
4.2、finishBeanFactoryInitialization()初始化剩下的单实例bean
4.2.1、创建业务逻辑组件和切面组件
4.2.2、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
4.2.3、组件创建完之后,判断组件是否需要增强是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
5、执行目标方法:
5.1、代理对象执行目标方法
5.2、CglibAopProxy.intercept();
5.2.1、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
5.2.2、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
5.2.3、效果:
正常执行:前置通知-》目标方法-》后置通知-》返回通知
出现异常:前置通知-》目标方法-》后置通知-》异常通知