AOP面向切面编程
aop专门用来处理系统中分布于各个模块中交叉关注点的问题,常常用来处理例如:安全检查、缓存、对象池管理等。
即:例如银行系统有 流程a 验证用户->查询余额->结束;流程b 验证用户->取款->结束。a和b中都有验证用户这一公共模块,那么就可以把验证用户单独取出来,这就是aop。在写代码的时候,只考虑主流程,而不用考虑哪些不是很重要的流程。
先写一个例子
目标类
@Component
public class Calcutor {
public int div(int i, int j) {
System.out.println("目标方法开始运行");
return i/j;
}
}
切面类
/**
* @Description: 日志切面类
* 日志切面类可以动态感知到方法的运行
* 通知方法:
* 前置通知(@Before):目标方法运行之前
* 后置通知:目标方法运行之后
* 返回通知:目标方法正常返回之后运行(目标方法异常不允许)
* 异常通知:目标方法出现异常后运行
* 环绕通知:动态代理,需要手动执行joinPoint.procced()
*
* 可以通过joinPoint 获取方法信息
*/
@Aspect
public class LogAspects {
/**
* 声明需要切入的目标
* execution
* 完整写法 execution(public int com.zxl.aop.bean.Calcutor.div(int, int))
* 指定类中任意方法 execution(public int com.zxl.aop.bean.Calcutor.*(..))
*/
@Pointcut("execution(public int com.zxl.aop.bean.Calcutor.*(..))")
public void pointCut() {
}
/**
* 代表在目标方法之前切入,并指定方法
*/
// @Before("execution(public int com.zxl.aop.bean.Calcutor.*(..))")
@Before("pointCut()")
// public void logStart() {
// System.out.println("@Before--方法之前--->");
// }
public void logStart(JoinPoint joinPoint) {
System.out.println("@Before--方法之前--->方法名" +joinPoint.getSignature().getName()
+ "参数-->" + Arrays.asList(joinPoint.getArgs()));
}
/**
* 代表在目标方法之后切入,并指定方法
*/
@After("pointCut()")
public void logEnd() {
System.out.println("@After--方法之后--->");
}
/**
* 目标方法正常返回之后
*/
@AfterReturning(value = "pointCut()", returning = "obj")
// public void logReturn() {
System.out.println("@AfterReturning--方法正常返回--->");
}
public void logReturn(Object obj) {
System.out.println("@AfterReturning--方法正常返回--->"+ obj);
}
/**
* 目标方法异常之后
*/
// @AfterThrowing("pointCut()")
// public void logException() {
// System.out.println("@AfterThrowing--方法运行异常--->");
// }
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void logException(Exception exception) {
System.out.println("@AfterThrowing--方法运行异常--->" + exception.getMessage());
}
/**
* 环绕
* @param joinPoint
*/
@Around("pointCut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 还在before之前
System.out.println(" @Around执行目标方法之前--->");
// 动态代理,通过反射调用目标方法
Object proceed = joinPoint.proceed();
System.out.println(" @Around执行目标方法之后--->");
return proceed;
}
}
AnnotationAwareAspectJAutoProxyCreator AOP工具类创建流程
- register()传入配置类,准备创建ioc容器
- 注册配置类,调用refresh()刷新创建容器
- registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建(主要是创建AnnotationAwareAspectJAutoProxyCreator)
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有的BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 先注册实现了PriorityOrdered的BeanPostProcessor,添加到beanfactory
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 再注册实现了Ordered的BeanPostProcessor,添加到beanfactory
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 最后注册剩余的BeanPostProcessor,添加到beanfactory
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
}
- 跟进去beanFactory.getBean(ppName, BeanPostProcessor.class),一直跟到doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
再跟进去createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
try {
//去创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
再跟进 doCreateBean(beanName, mbdToUse, args);
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable 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);
}
Object exposedObject = bean;
try {
// Bean属性赋值.应用Bean属性的值;为属性利用setter方法等进行赋值
// 赋值拿到后置处理器,执行后置处理器的方法
populateBean(beanName, mbd, instanceWrapper);
//Bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
return exposedObject;
}
- 到此AnnotationAwareAspectJAutoProxyCreator就创建完了,其实他跟普通的bean创建流程一样,只不过是创建的时机不同。
创建增强bean的流程
- refresh方法中的finishBeanFactoryInitialization(beanFactory)方法
- 遍历获取容器中所有bean,如果获取不到就进行创建
public void preInstantiateSingletons() throws BeansException {
// 上面的代码省略
for (String beanName : beanNames) {
// 获取bean的定义信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 判断是否懒加载、是否单实例、是否抽象的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
}
}
}
else {
// 都不是,则获取bean
getBean(beanName);
}
}
// 将创建的Bean添加到缓存中singletonObjects,其实就是放进了map中
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();
}
}
}
}
}
- 跟进getBean一直到doGetBean方法,再进入createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
try {
// 让BeanPostProcessor先拦截返回代理对象;
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
// 开始创建实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
}
- 进入resolveBeforeInstantiation(beanName, mbdToUse)方法
@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 = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
// 最终返回null
return bean;
}
- 再次跟进去doCreateBean(beanName, mbdToUse, args);
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable 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);
}
Object exposedObject = bean;
try {
// Bean属性赋值.应用Bean属性的值;为属性利用setter方法等进行赋值
// 赋值拿到后置处理器,执行后置处理器的方法
populateBean(beanName, mbd, instanceWrapper);
//Bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
return exposedObject;
}
- 跟进去initializeBean(beanName, exposedObject, mbd);
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;
}
- 跟进去applyBeanPostProcessorsAfterInitialization,再跟进去postProcessAfterInitialization,再跟进去AbstractAutoProxyCreator类的postProcessAfterInitialization。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
- 如果是切面类。那么就继续往下走wrapIfNecessary()。在这一步就找到目标类的所有通知方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
// 获取到目标类关联的所有通知方法
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
- 通过代理工厂创建增强bean
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
return proxyFactory.getProxy(this.getProxyClassLoader());
}
- 通过JDK动态代理或者CGLIB动态代理
跟进去proxyFactory.getProxy(this.getProxyClassLoader());,再跟进去createAopProxy(),再跟进去createAopProxy()
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
// 如果实现了接口那么就使用jdk代理
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
- 给容器中返回增强后的代理对象
- 执行目标方法的时候,代理对象会执行通知方法的流程
执行目标方法(切面拦截)的流程
- CglibAopProxy.intercept();拦截目标方法的执行
- 根据ProxyFactory对象获取将要执行的目标方法拦截器链;List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- List<Object> interceptorList保存所有拦截器 5个 一个默认的ExposeInvocationInterceptor 和 4个增强器
- 遍历所有的增强器,将其转为Interceptor; registry.getInterceptors(advisor);
- 将增强器转为List<MethodInterceptor>;如果是MethodInterceptor,直接加入到集合中。如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;转换完成返回MethodInterceptor数组;
- 如果没有拦截方法,那么直接执行目标方法
- 如果有则采用拦截器的链式机制,依次进入每一个拦截器进行执行
每一个通知方法都有其专门的处理拦截类
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
Object var16;
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = target != null ? target.getClass() : null;
// 根据ProxyFactory对象获取将要执行的目标方法拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
} else {
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
}
retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
var16 = retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return var16;
}
进入proceed();
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
// 获取第一个通知方法
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
调用invoke方法,再invoke方法中又会调用proceed()方法,遍历所有的增强器,这里只列举了三个,可以看到只有MethodBeforeAdviceInterceptor是先执行逻辑,再执行proceed,然后一层层执行其它的增强器。
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
invocation.set(mi);
Object var3;
try {
var3 = mi.proceed();
} finally {
invocation.set(oldInvocation);
}
return var3;
}
public Object invoke(MethodInvocation mi) throws Throwable {
Object var2;
try {
var2 = mi.proceed();
} finally {
this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
}
return var2;
}
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}