目录
一、前言
二、源码分析
三、特别说明
AOP(Aspect Oriented Programming 面向切面编程)是Spring框架的核心功能之一,关于AOP中一些概念的理解可以参考 SpringAOP概念及其使用 ,下面以一个简单的例子作为Spring AOP源码学习的起点。
首先,定义一个切面类CustomAspect,如下所示:
public class CustomAspect {
public void before() {
System.out.println("Before custom operation");
}
public void after() {
System.out.println("After custom operation");
}
}
然后,在配置文件中定义Bean、切面、切入点、通知等,如下所示:
USER
ADMIN
最后,通过如下代码获取到IOC容器中名为 a 的Bean:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
A a = (A) applicationContext.getBean("a");
a.say();
运行结果如下:
Before custom operation
123 Alvin [USER, ADMIN]
After custom operation
从上面的例子中可以看到,say方法在执行前后分别执行了CustomAspect中的before和after方法,于是我们就需要思考一个问题:Spring是在什么地方对Bean进行了改造的?
经过上一章的分析,我们知道getBean方法作为调用起点,完成了Bean的创建和依赖注入,构造了一个完整的Bean返回给用户使用,那么AOP对Bean的改造应当是在依赖注入之后,返回给用户之前,下面带着这个疑问,回到源码中继续学习。
在AbstractAutowireCapableBeanFactory类的doCreateBean方法中,我们可以发现如下代码:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
/**
* 真正开始创建Bean
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
......
// 初始化bean
Object exposedObject = bean;
try {
// 这里开始进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean,执行Initialization BeanPostProcessor
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);
}
}
......
// 返回Bean实例,这里已经完成了依赖注入
return exposedObject;
}
}
在这里,我们发现在依赖注入之后,返回给用户之前,调用了initializeBean方法,下面一起看看这个方法的实现:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
在上面的代码中我们发现最终调用了BeanPostProcessor接口的相关方法,我们以接口的实现类AspectJAwareAdvisorAutoProxyCreator为例看看后置处理器的实现,首先来看一下AspectJAwareAdvisorAutoProxyCreator的类继承图(省略了部分接口):
从图中可以看到AspectJAwareAdvisorAutoProxyCreator间接实现了BeanPostProcessor接口,接口方法的实现在其父类AbstractAutoProxyCreator中,如下所示:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
/**
* before初始化
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
/**
* after初始化
*/
@Override
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;
}
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;
}
// 获取通知数组
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;
}
/**
* 创建代理
*/
protected Object createProxy(Class> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 代理工厂,提供了非配置方式的编程式使用方式
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// proxyFactory.isProxyTargetClass() 默认为false
if (!proxyFactory.isProxyTargetClass()) {
// 是否代理目标类,也就是对节点的proxy-target-class属性进行判断
// 为true时表示通过CGLIB进行代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
// 为false时表示通过JDK进行代理,需要实现接口
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);
}
// 创建并返回代理对象
// 根据配置或由Spring自动决定使用JDK或CGLIB方式生成代理对象
// 最终实现在DefaultAopProxyFactory类中
return proxyFactory.getProxy(getProxyClassLoader());
}
}
这段代码返回了一个代理对象,从而阻止了Bean默认的实例化操作,代理对象的创建由ProxyFactory完成,下面让我们来看一看ProxyFactory的具体实现,代码如下:
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
// 这里的createAopProxy()方法定义在父类ProxyCreatorSupport中
return createAopProxy().getProxy(classLoader);
}
}
ProxyCreatorSupport代码如下:
public class ProxyCreatorSupport extends AdvisedSupport {
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 这里的getAopProxyFactory默认返回一个DefaultAopProxyFactory对象
return getAopProxyFactory().createAopProxy(this);
}
}
DefaultAopProxyFactory代码如下:
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
/**
* 根据配置或由Spring自动优化决定使用JDK动态代理还是CGLIB生成代理对象
*/
@Override
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);
}
}
}
从上面的代理中可以看到,最终调用了JdkDynamicAopProxy或ObjnesisCglibAopProxy的getProxy方法获得了一个代理对象,这里以JdkDynamicAopProxy为例看一看具体实现:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
可以看到最终通过Java的反射机制创建了代理对象并返回给了用户,至此AOP代理对象的创建过程就完成了。
对BeanDefinition解析比较了解的同学可能记得解析工作是委托给BeanDefinitionParserDelegate完成的,在这个类的parseCustomElement方法中,会根据<>元素标签的命名空间取得相应的NamespaceHandler,并通过Handler的parse方法来解析元素,比如对于
在AopNamespaceHanlder中定义了一系列的BeanDefinitionParser,当解析
configureAutoProxyCreator(parserContext, element);
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
这部分代码表示Spring默认提供了一个AspectJ的代理生成器,这就是为什么上文中以AspectJAwareAdvisorAutoProxyCreator为例分析代理对象的生成过程。