1.设计原理
在Spring中是通过配置和调用Spring的ProxyFactoryBean来生成代理对象的,在这个过程中可以使用JDK的Proxy和CGLIB两种生成方式。ProxyFactory的继承体系如下图:
由继承体系可见,对于需要使用AspectJ的AOP应用,AspectJProxyFactory起到集成Spring和AspectJ的作用;使用ProxyFactoryBean可以在IOC容器中完成声明式配置,而使用ProxyFactory则需要编程式地使用Spring AOP功能。
2.配置ProxyFactoryBean
(1)定义使用的通知器Advisor,这个通知器应该作为一个Bean来定义。
(2)定义ProxyFactoryBean,把它作为另一个Bean来定义,它是封装AOP功能的类。
(3)定义target属性,作为target属性注入的Bean,是需要用AOP通知器中的切面应用来增强的对象。
3.ProxyFactoryBean生成AopProxy代理对象
具体的AopProxy生成过程如下图:
从ProxyFactoryBean中获取对象是以getObject()方法为入口的。
public Object getObject() throws BeansException {
// 这里初始化通知器链
initializeAdvisorChain();
// 这里对singleton和prototype的类型进行区分,生成对应的proxy
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}
对通知器链的初始化工作是在应用第一次通过ProxyFactoryBean获取代理对象的时候。
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the property...
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
// 这里是添加Advisor链的调用,是通过interceptorNames属性进行配置的
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
// 如果程序在这里被调用,那么需要加入命名的拦截器advice,
// 并且需要检查这个Bean是singleton还是prototype类型
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
// 加入advice或者advisor
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
Spring通过AopProxy类来具体生成代理对象,通过getSingletonInstance方法生成。
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// 根据AOP框架来判断需要代理的接口
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
// 这里设置代理对象的接口
}
super.setFrozen(this.freezeProxy);
// 使用ProxyFactory来生成需要的Proxy
}
return this.singletonInstance;
}
// 通过createAopProxy返回的AopProxy来得到代理对象
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);}
AopProxy是一个接口,它由两个子类实现,一个是Cglib2AopProxy,另一个是JdkDynamicProxy。这里使用了AopProxyFactory来创建AopProxy,AopProxyFactory使用的是DefaultAopProxyFactory。如果目标对象是接口类,那么适合使用JDK来生成代理对象,否则Spring会使用CGLIB来生成目标对象的代理对象。具体的是由JdkDynamicAopProxy和CglibProxyFactory类来完成的。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 通过AopProxyFactory取得AopProxy,这个AopProxyFactory是在初始化函数中
// 定义的,使用的是DefaultProxyFactroy
}
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.");
}
// 如果目标对象是接口来,使用JDK来生成Proxy
return new JdkDynamicAopProxy(config);
}
// 否则用CGLIB来生成
}
else {
return new JdkDynamicAopProxy(config);
}
}
4.JDK生成AopProxy代理对象
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);
// 调用jdk生成Proxy
}
5.CGLIB生成AopProxy代理对象
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
// 从advised中取得在IoC容器中配置的target对象
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建并配置enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置Enhancer对象,包括代理接口,回调方法
// 使用Aop的DynamicAdvisedInterceptor拦截器
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 通过Enhancer生成代理对象
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}