Aop原理
1.分析入口@EnableAspectJAutoProxy
1.@EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar
利用AspectJAutoProxyRegistrar自定义给容器中注册bean;
internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
给容器中注册一个AnnotationAwareAspectJAutoProxyCreator
2.AnnotationAwareAspectJAutoProxyCreator的作用
2.AnnotationAwareAspectJAutoProxyCreator的作用
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
->implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
关注后置处理器(可以在bean初始化前后进行操作),自动装配BeanFactory做了什么事情
3.AbstractAutoProxyCreator.setBeanFactory()
3.AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.后置处理器逻辑
AbstractAdvisorAutoProxyCreator.setBeanFactory() -》initBeanFactory
AbstractAdvisorAutoProxyCreator.initBeanFactory()
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
在这几个地方打上断点
4.启动容器
4.启动容器
基本流程
(1)传入配置类(配置类中传入了internalAutoProxyCreator)
(2)注册配置类,调用refresh(),刷新容器;
(3)registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建;
1)先获取ioc容器已经定义了的需要创建的BeanPostProcessor组件
2)给容器中加入别的BeanPostProcessor
3)优先注册实现了PriorityOrdered接口的BeanPostProcessor;
4)再给容器中注册实现了Ordered接口的BeanPostProcessor;
5)注册没实现优先级接口的BeanPostProcessor;
6)注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
1)创建Bean的实例;
2)populateBean(beanName, mbd, instanceWrapper);
3)initializeBean:初始化bean
1)invokeAwareMethods():处理Aware接口,让bean对象能感知到容器的存在,从容器中获取一些东西
2)applyBeanPostProcessorsBeforeInitialization():应用后置处理器的beanPostProcessorsBeforeInitialization()
3)invokeInitMethods():执行自定义的初始化方法
4)applyBeanPostProcessorsAfterInitialization():执行后置处理器的beanPostProcessorsAfterInitialization()
4)BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功:aspectJAutoProxyBuilder
以上为创建和注册AnnotationAwareAspectJAutoProxyCreator的过程
5.执行时机
5.执行时机
AnnotationAwareAspectJAutoProxyCreator -》InstantiationAwareBeanPostProcessor
finishBeanFactoryInitialization(beanFactory);完成单实例bean的创建
1)遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
getBean ->doGetBean() ->getSigleton()->
2)创建bean
1)先从缓存中获取当前Bean,如果获取到,直接使用;
只要创建好的bean会被缓存起来
2)createBean();创建bean
1)resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation,希望后置处理器在此能够返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
后置处理器先尝试返回对象;
bean = applyBeanPostProcessorsBeforeInstantiation();
拿到后置处理器,如果bean是InstantiationAwareBeanPostProcessor则会调用postProcessBeforeInstantiation()方法;
如果返回bean不为空,则继续调用applyBeanPostProcessorsAfterInitialization方法
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
2)doCreateBean(beanName, mbdToUse, args);
1)创建Bean的实例;
2)populateBean(beanName, mbd, instanceWrapper);
3)initializeBean:初始化bean
1)invokeAwareMethods():处理Aware接口,让bean对象能感知到容器的存在,从容器中获取一些东西
2)applyBeanPostProcessorsBeforeInitialization():应用后置处理器的beanPostProcessorsBeforeInitialization()
3)invokeInitMethods():执行自定义的初始化方法
4)applyBeanPostProcessorsAfterInitialization():执行后置处理器的beanPostProcessorsAfterInitialization()
6.创建代理
6.创建代理
根据上面的分析,会调用到
1)AbstractAutoProxyCreator.postProcessBeforeInstantiation()
1)判断当前bean是否在advisedBeans中(保存了所有需要增强的bean)
2)判断当前bean是否是基础类型的Advice,Pointcut,Advisor,AopInfrastructureBean或者是否是切面(@Aspect)
3)是否需要跳过
1)获取候选增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
每一个封装的通知方法的增强器是InstantianModelAwarePointAdvisor;
判断每一个增强器是否是AspectJPointcutAdvisor类型的;返回true
2)永远返回false
2)创建对象
AbstractAutoProxyCreator.postProcessorsAfterInitialization();
return wrapIfNecessary(bean, beanName, cacheKey);包装如果有需要的情况下
1)获取当前bean的所有增强方法(即我们的通知方法,before,after等等) Obejct[] specifcInterceptors
1)找到候选的所有增强器(找哪些通知方法是需要切入当前bean方法的)
2)获取到能在bean使用的增强器.
3)给增强器排序
2)保存当前bean在advisedBeans中;
3)如果当前bean需要增强,则创建当前bean代理对象
1)获取所有增强器(通知方法)
2)保存到proxyFactory
3)创建代理对象
JdkDynamicAopProxy(AdvisedSupport config);jdk动态代理
CglibAopProxy(AdvisedSupport config);cglib动态代理
4)返回代理对象
5)以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程.
AbstractAutoProxyCreator.postProcessorsAfterInitialization();代码如下
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;
}
postProcessorsAfterInitialization()代码如下
public Object postProcessAfterInitialization(@Nullable 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;
}
AbstractAutoProxyCreator#wrapIfNecessary源码如下
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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;
}
调用了createProxy()
最终会调用到
DefaultAopProxyFactory.createAopProxy(AdvisedSupport config)
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动态代理,当然也可以通过配置参数Optimize=true 或ProxyTargetClass="cglib"来使用cglib动态代理
7.获取拦截器链MethodInterceptor
目标方法执行;
容器中保存了组件的代理对象(cglib增强后的对象),这个对象里保存了详细信息(比如增强器,目标对象,xxx);
1)CglibAopProxy.intercept();拦截目标方法的执行;
2)根据ProxyFactory对象获取将要执行的目标方法拦截器链;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
1)List<Object> interceptorList 保存所有拦截器5
一个默认的ExposeInvocationInterceptor和4个增强器
2)遍历所有的增强器,将其转为Interceptor;
registry.getInterceptors(advisor);
3)将增强器转为List<MethodInterceptor>;
如果是MethodInterceptor,直接加入到集合中
如果不是,使用AdvisorAdaptor将增强器转为MethodInterceptor;
转换完成返回MethodInterceptor数组;
3)如果没有拦截器链,直接执行目标方法;
拦截器链(每一个方法又被包装为方法拦截器,利用MethodInterceptor机制)
4)如果有拦截器链,把需要执行的目标对象,目标方法,拦截器等信息传入
创建一个CglibMethodInvocation对象,并调用Object retVal =mi.proceed();
5)拦截器链的触发过程
1)
8.拦截器链的触发过程
mi.proceed()的执行
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
满足长度相等的条件,就真正去执行目标方法了
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
事务原理
1.@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中导入了两个组件
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
2.AutoProxyRegistrar
给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件;
InfrastructureAdvisorAutoProxyCreator的作用
就是利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行处理
3.ProxyTransactionManagementConfiguration
1.给容器中注册事务增强器
(1)事务增强器需要的事务注解信息,AnnotationTransactionAttributeSource解析事务
(2)事务拦截器
TransactionInterceptor;保存了事务属性信息,事务管理器;
同时它是一个MethodInterceptor;
在目标方法执行的时候;
执行拦截器链;
事务拦截器:
①先获取事务相关属性
②再获取PlatformTranactionManager,如果没有先添加指定任何PlatformTranactionManager,最终会从容器中按照类型获取一个PlatformTranactionManager
③执行目标方法
如果异常,获取到事务管理器,利用事务管理器回滚操作;
如果正常,利用事务提交,进行提交
整个调用链条如下
org.springframework.transaction.interceptor.TransactionInterceptor.invoke
->org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction
->org.springframework.transaction.interceptor.TransactionAspectSupport.getTransactionAttributeSource 获取事务相关属性
->org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager 再获取PlatformTranactionManager
->org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary
->org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction 事务的传播属性就是在这个方法里面判断的
->org.springframework.jca.cci.connection.CciLocalTransactionManager.doBegin 获取底层数据库连接
->org.springframework.transaction.interceptor.TransactionAspectSupport.InvocationCallback.proceedWithInvocation 执行目标方法
->org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing 异常则回滚事务
->org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning 成功则提交事务
代码如下
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
.....
}
invoke()方法
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
invokeWithinTransaction()方法
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
先获取事务相关属性
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
再获取PlatformTranactionManager
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if是声明式事务,else是编程式事务
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
rollback回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
getTransaction()方法
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction();
// Cache debug flag to avoid repeated checks.
boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
}
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// No existing transaction found -> check propagation behavior to find out how to proceed.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
doBegin()方法
protected void doBegin(Object transaction, TransactionDefinition definition) {
CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
ConnectionFactory connectionFactory = obtainConnectionFactory();
Connection con = null;
try {
con = connectionFactory.getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + con + "] for local CCI transaction");
}
ConnectionHolder connectionHolder = new ConnectionHolder(con);
connectionHolder.setSynchronizedWithTransaction(true);
con.getLocalTransaction().begin();
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
connectionHolder.setTimeoutInSeconds(timeout);
}
txObject.setConnectionHolder(connectionHolder);
TransactionSynchronizationManager.bindResource(connectionFactory, connectionHolder);
}
catch (NotSupportedException ex) {
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex);
}
catch (LocalTransactionException ex) {
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
throw new CannotCreateTransactionException("Could not begin local CCI transaction", ex);
}
catch (Throwable ex) {
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
throw new TransactionSystemException("Unexpected failure on begin of CCI local transaction", ex);
}
}