一 例子
通过ProxyFactoryBean实现对Person的代理,不需要修改代码Person,只需要配置:
public interface IPerson {
public String queryName();
}
public class Person implements IPerson {
private String name;
public String queryName() {
System.out.println("name:" + name);
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class PersonAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before......");
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("afterReturning......");
}
}
<bean id="person" class="com.myframe.modules.test.service.impl.Person">
<property name="name" value="zhangsan"></property>
</bean>
<!-- 准备切点跟advice -->
<bean id="beforeAfterAdvice" class="com.myframe.modules.test.service.impl.PersonAdvice">
</bean>
<bean id="queryPointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*query.*"></property>
</bean>
<bean id="queryAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="beforeAfterAdvice"></property>
<property name="pointcut" ref="queryPointCut"></property>
</bean>
<bean id="personProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="person"/>
<property name="interceptorNames" value="queryAdvisor" />
</bean>
指定ProxyFactoryBean对象名称为personProxy,并指定目标对象和拦截对象,获取的personProxy对象实际上就是一个代理过的对象,调用其方法queryName的到打印结果:
before......
name:zhangsan
afterReturning......
二 源码走读
回顾前面的BeanFactory,获取personProxy对象走到doGetBean方法,doGetBean中获得对象后都会调用一句getObjectForBeanInstance方法,这里是实现代理的核心逻辑,它的核心思想是判断对象是否是FactoryBean,如果是则调用其getObject方法。
上面使用的ProxyFactoryBean是FactoryBean的子类,看它的getObject方法:
public Object getObject() throws BeansException {
initializeAdvisorChain();
if (isSingleton()) {
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();
}
}
主要分两步:
1. initializeAdvisorChain
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");
}
// Materialize interceptor chain from bean names.
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 {
// If we get here, we need to add a named interceptor.
// We must check if it's a singleton or prototype.
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
// Add the real Advisor/Advice to the chain.
advice = this.beanFactory.getBean(name);
} else {
// It's a prototype Advice or Advisor: replace with a
// prototype.
// Avoid unnecessary creation of prototype bean just for
// advisor chain initialization.
advice = new PrototypePlaceholderAdvisor(name);
}
//放到集合中
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
这边就是将配置的interceptorNames对应的对象初始化好放到advisors集合中,如果带有*结尾的就把beanFactory中所有命中的前缀都加进来,advisorChainInitialized会标记是否已经处理过,保证只会被加载一次。
2. 实例化
这里以单例模式看代理对象的创建,看方法getSingletonInstance():
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to
// proxy.
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// Initialize the shared singleton instance.
super.setFrozen(this.freezeProxy);
//先获取aop proxy对象
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//先获取创建AopProxy的工厂, 再由此创建AopProxy
return getAopProxyFactory().createAopProxy(this);
}
根据方法调用可以看出先获取AopProxyFactory,然后创建AopProxy,再通过AopProxy创建代理对象。
AopProxyFactory默认就一个实现DefaultAopProxyFactory,看它的createAopProxy方法:
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()) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
这个地方就看出spring是分别什么条件下使用jdk或cglib的动态代理了,总结如下:
- 如果目标对象实现了接口,默认用jdk proxy,也可以通过配置指定使用cglib
- 如果目标对象没有实现接口,必须用cglib
下面就是根据两种AopProxy创建代理对象的逻辑了:
如果返回的是JdkDynamicAopProxy则创建代理的方法:
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
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);
//标准的jdk proxy用法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
如果返回的是ObjenesisCglibAopProxy则创建代理的方法:
@Override
public Object getProxy() {
return getProxy(null);
}
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
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);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass);
//创建配置Enhancer
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader
&& ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
//回调
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);
//创建代理
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException 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 (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 (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
这就是用cglib创建代理对象的范畴了。