传统的面向对象编程是自上而下的,而有时候会产生一些横切性问题,并且这些横切性问题和我们的主业务逻辑关系不大时,这些横切性问题不会影响到主业务逻辑的实现,但是会散落到代码的各个部分,导致难以维护。AOP,即面向切面编程,其可以处理这些横切性问题,AOP编程的思想就是将这些问题与主业务逻辑分开,以达到与主业务逻辑解耦的目的,使代码的重用性和开发效率更高。
AOP具有以下几个常见的应用场景:
Spring AOP是AOP编程思想的一种实现方式,在Spring中,其采用了AspectJ对AOP的实现风格,使用AspectJ的注解方式来实现AOP。Spring AOP中具有如下概念和术语:
首先,我们可以通过注解或者XML配置的方式开启Spring AOP,在开启成功后,Spring容器会自动实例化一个AnnotationAwareAspectJAutoProxyCreator对象,用于实现AOP,该对象是一个BeanPostProcessor。读者可以试一下,不开启Spring AOP的话是不会实例化这个BeanPostProcessor的。
既然我们知道了Spring AOP是由AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor来实现的,那了解Spring IOC的读者就知道,在Spring初始化时,在最后会对相关的Bean进行初始化,在初始化时候会调用BeanPostProcessor的相关方法,初始化方法实现如下:
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()) {
// 调用BeanPostProcessor的postProcessBeforeInitialization()方法
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()) {
// 调用BeanPostProcessor的postProcessAfterInitialization()方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
在初始化方法里面会首先调用相应的Aware方法;然后调用所有BeanPostProcessor的postProcessBeforeInitialization()方法;若该bean实现了InitializingBean接口,则会调用相应的afterPropertiesSet()方法;接着会调用所有BeanPostProcessor的postProcessAfterInitialization()方法,而Spring的AOP就是在该方法中实现的。下面看AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法具体实现。
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;
}
该方法首先判断该bean之前是否被代理过,若未被代理过,则进行相应的代理,也就是调用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;
}
// 如果该bean配置了相关的advisor,即相关的advise和pointcut,则创建相关的代理对象
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是否需要被代理,如果需要的话,则调用createProx()方法创建代理对象,具体实现如下:
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//首先创建代理工厂实例,用于后续创建代理对象
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);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 获取代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
ProxyFactory的getProxy方法的具体实现如下:
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
上述方首先创建一个AopProxy对象,用于产生最终得到相关的代理对象。其中createAopProxy()方法的具体实现如下:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
首先通过getAopProxyFactory()方法获取AOP代理工厂,然后通过所获取的AOP代理工厂创建AOP代理,具体实现如下:
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);
}
}
其中AOP代理具有两种实现方,一种是使用Jdk的动态代理,一种是使用Cglib的动态代理方式,该方法通过判断目标类是否存在接口,以及外部是否强制使用cglib代理等条件来判断最终使用哪种代理方式。
在获得具体的AopProxy对象之后,就可以获取具体的代理对象了,其中Jdk的动态代理对象中的getProxy()方法实现如下:
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
熟悉Jdk动态代理的读者看到这就知道了,最终通过roxy.newProxyInstance(classLoader, proxiedInterfaces, this);来获取最终的代理对象。