1.3.1 创建代理
获取所有对应bean的增强器后, 就可以进行代理的创建了
回顾wrapIfNecessary方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经处理过(targetSourcedBeans存放已经增强过的bean)
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//advisedBeans的key为cacheKey,value为boolean类型,表示是否进行过代理
//已经处理过的bean,不需要再次进行处理,节省时间
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//给定的bean类是否已经代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
//如果一个bean继承自Advice、Pointcut、Advisor、AopInfrastructureBean 或者 带有@Aspect注解,或被Ajc(AspectJ编译器)编译都会被认定为内部基础设置类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//获取所有适合该bean的增强Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果获取的增强不为null,则为该bean创建代理(DO_NOT_PROXY=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生成代理:
创建代理:
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//在bean对应的BeanDefinition中添加原Class对象属性(保存bean原本的Class)
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
//获取当前类中相关属性
proxyFactory.copyFrom(this);
//检查proxyTargetClass属性是否为false(即不使用CGLIB代理)
if (!proxyFactory.isProxyTargetClass()) {
//判断是否需要使用CGLib进行代理
if (shouldProxyTargetClass(beanClass, beanName)) {
//添加代理接口
proxyFactory.setProxyTargetClass(true);
}
//使用JDK的动态代理来创建代理
else {
//筛选代理接口并添加到proxyFactory
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//获取增强器(包括前面筛选出来的增强器,以及通过setInterceptorNames中添加的通用增强器,默认为空)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
//将所有增强器添加到proxyFactory
proxyFactory.addAdvisor(advisor);
}
//设置需要代理的bean对象信息
proxyFactory.setTargetSource(targetSource);
//模版方法,由子类定制化代理
customizeProxyFactory(proxyFactory);
//用来控制代理工厂被配置之后,是否还允许修改通知
//缺省值为false(即在代理被配置之后,不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
逻辑分析:
对于代理类的创建及处理, spring委托给了ProxyFactory去处理, 而在此函数中主要是对ProxyFactory的初始化操作, 进而对真正的创建代理做准备:
(1) 获取当前类中的属性
(2) 添加代理接口
(3) 封装Advisor并加入到ProxyFactory中
(4) 设置要代理的类
(5) 在spring中还为子类提供了定制的函数customizeProxyFactory, 子类可以在此函数中进行对ProxyFactory的进一步封装
(6) 进行获取代理操作
1. 封装Advisor:
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
//拦截注册的所有interceptorName
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<Object>();
if (specificInterceptors != null) {
//1.加入已过滤的拦截器
allInterceptors.addAll(Arrays.asList(specificInterceptors));
//2.加入通过setInterceptorNames中添加的通用增强器
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isDebugEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
//拦截器进行封装转换为Advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果要封装的对象本身就是Advisor类型,那么无需再做过多处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//因为此封装方法只对Advisor与Advice两种类型的数据有效,如果不是将不能封装
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
//如果是MethodInterceptor类型,则使用DefaultPointcutAdvisor封装
return new DefaultPointcutAdvisor(advice);
}
//如果存在Advisor的适配器,那么也同样需要封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
2. 创建代理
return proxyFactory.getProxy(getProxyClassLoader())
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
//active会在在第一次创建代理后,设为true
if (!this.active) {
//设置active为true,并通知监听器(如果没有配置,为空)
activate();
}
//getAopProxyFactory会返回aopProxyFactory变量,默认实现为DefaultAopProxyFactory
return getAopProxyFactory().createAopProxy(this);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
//代理目标bean的Class不能为空
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation.");
}
//如果是接口 或者 Class类型为Proxy(优先使用JDK方式)
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
逻辑分析:
在createAopProxy(AdvisedSupport config)方法中有两种spring代理的实现, 一种是JDKProxy的实现, 另一种是Cglib的实现; 从if的判断条件可以看到3个方面影响着spring的判断
- optimize: 用来控制通过CGLIB创建的代理是否使用激进的优化策略; 除非完全了解AOP代理如何处理优化, 否则不推荐用户使用这个设置; 目前这个属性进用于CGLIB代理, 对于JDK动态代理无效
- proxyTargetClass: 这个属性为true时, 目标类本身被代理而不是目标类的接口, 如果这个属性值被设为true, CGLIB代理将被创建, 设置方式: <aop:aspectj-autoproxy proxy-target-class =“true” />
- hasNoUserSuppliedProxyInterfaces: 是否存在代理接口
下面是对JDK与CGLIB方式的总结:
- 如果目标对象实现了接口, 默认情况下会采用JDK的动态代理实现AOP
- 如果目标对象实现了接口, 可以强制使用CGLIB实现AOP
- 如果目标对象没有实现任何接口, 必须采用CGLIB库, spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB库实现AOP?
(1) 添加CGLIB库, Spring_HOME/cglib/*.jar
(2) 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class =“true” />
JDK动态代理与CGLIB字节码生成的区别?
(1) JDK动态代理只能对实现了接口的类生成代理, 而不能针对类
(2) CGLIB是针对类实现代理, 主要是对指定的类生成一个子类, 覆盖其中的方法, 因为是继承, 所以该类或方法最好不要声明为final
获取代理:
1、JDK代理使用示例
(1) 创建业务接口, 业务对外提供的接口, 包含着业务可以对外提供的功能
public interface UserService{
//目标方法
public abstract void add();
}
(2) 创建业务接口实现类
public class UserService implements UserService {
public void add(){
System.out.println("------------------add---------------");
}
}
(3) 创建自定义的InvocationHandler, 用于对接口提供的方法进行增强
public class MyInvocationHandler implements InvocationHandler{
//目标对象
private Object target;
public MyInvocationHandler (Object target) {
super();
this.target = target;
}
//执行目标对象的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//在目标对象的方法执行之前打印提示信息
System.out.println("------------------before---------------");
//执行目标对象的方法
Object result = method.invoke(target, args);
//在目标对象的方法执行之后打印提示信息
System.out.println("------------------after---------------");
return result;
}
//获取目标对象的代理对象
public Object getProxy(){
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
}
}
(4) 进行测试, 验证对于接口的增强是否起到作用
@Test
public class ProxyTest{
public void testProxy() throws Throwable{
//实例化目标对象
UserService userService= new UserServiceImpl();
//实例化InvocationHandler
MyInvocationHandler invocationHandler =new MyInvocationHandler (userService);
//根据目标对象生成代理对象
UserService proxy = (UserService) invocationHandler .getProxy();
//调用代理对象的方法
proxy.add();
}
}
控制台输出:
------------------before---------------
------------------add------------------
------------------after-----------------
用起来很简单, 其实这就是一个AOP的简单实现, 在目标对象的方法执行之前和执行之后进行了增强; spring的AOP实现其实也就是用了Proxy和InvocationHandler这两个东西; 在整个创建过程中, 对于InvocationHandler的创建是最为核心的, 在自定义的InvocationHandler中需要重写3个方法
- 构造方法, 将代理的对象传入
- invoke方法, 此方法中实现了AOP增强的所有逻辑
- getProxy方法, 此方法千篇一律, 但是必不可少
接下来看下spring中的JDK动态代理的实现:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
/** Config used to configure this proxy */
private final AdvisedSupport advised;
private boolean equalsDefined;
private boolean hashCodeDefined;
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
@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);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
//equals方法的处理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
//目标不实现equals(Object)方法本身
return equals(args[0]);
}
//hash方法的处理
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
//目标不实现hashCode()方法本身
return hashCode();
}
/**
* Class类的isAssignableFrom(class cls)方法:
* 如果调用这个方法的class或接口与参数cls表示的类或接口相同, 或者是参数cls表示的类或者接口的父类,则返回true
* 形象地:自身类.class.isAssignableFrom(自身类或子类.class) 返回true
* 例:
* System.out.println(ArrayList.class.isAssignableFrom(Object.class))
* //false
* System.out.println(Object.class.isAssignableFrom(ArrayList.class))
* //true
*/
//opaque属性,表示是否禁止将代理对象转换为Advised对象,默认是false
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//有时候目标对象内部的自我调用将无法实施切面中的增强则需要通过此属性暴露代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象信息
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//获取当前方法的拦截链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有任何拦截器,则调用直接对原目标对象调用方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//如果没有发现任何拦截器,那么直接调用切点方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//将拦截器封装在ReflectiveMethodInvocation,以便于使用其proceed进行链接表用拦截器
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//执行拦截器链
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
//返回结果
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// 特殊情况:为了防止方法返回"return this",返回原目标对象,会将返回值替换为代理对象
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
逻辑分析:
在invoke()方法中最主要的工作就是创建了一个拦截器链, 并使用ReflectiveMethodInvocation类进行了链的封装, 而在ReflectiveMethodInvocation类的proceed方法中实现了拦截器的逐一调用
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
public Object proceed() throws Throwable {
//执行完所有增强后执行切点方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//获取下一个要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//动态匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//不匹配则不执行拦截器
return proceed();
}
}
else {
/**
* 普通拦截器,直接调用,比如:
* ExposeInvocationInteceptor,
* DelegatePerTargetObjectIntroductInterceptor,
* MethodBeforeAdviceInterceptor,
* AspectJAroundAdvice,
* AspectJAfterAdvice
*/
//将this作为参数传递以保证当前实例中调用链的执行 存储
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
逻辑分析:
ReflectiveMethodInvocation中的主要职责是维护了链接调用的计数器, 记录着当前调用链接的位置, 以便链可以有序的进行下去, 那么在这个方法中并没有我们之前调用链接的位置, 以便链接可以有序地进行下去, 那么在这个方法中并没有我们之前设想的维护增强的顺序, 而是将此工作委托给了各个增强器, 是各个增强器在内部进行逻辑实现
2、CGLIB使用示例
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP框架使用,例如Spring AOP和dynaop,为他们提供方法的Interception(拦截)。最流行的ORMapping工具Hibernate也是使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock和JMock是通过使用模仿(moke)对象来测试Java代码的包,他们都通过使用CGLIB来Wie那些没有借口的类创建模仿(moke)对象。
CGLIB包的底层通过使用一个小而快的字节码处理框架ASM,来转换字节码并生产新的类。除了CGLIB包脚本语言例如Groovy和BeanShell也是使用ASM来生成java的字节码。当然不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都非常熟悉。
接下来我们就简单的回顾下CGLIB的使用。如下代码:
import org.omg.PortableInterceptor.Interceptor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLIBTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//设置要代理的类
enhancer.setSuperclass(CGLIBTest.class);
//设置回调, 即MethodInterceptor的实现类
enhancer.setCallback(new MethodInterceptorImpl());
CGLIBTest test = (CGLIBTest)enhancer.create();
test.test();
System.out.println(test);
}
public void test() {
System.out.println("CGLIB Test");
}
private static class MethodInterceptorImpl implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before invoke");
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("After invoke");
return result;
}
}
}
控制台输出:
Before invoke
CGLIB Test
After invoke
Before invoke
Before invoke
After invoke
After invoke
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);
}
}
//验证Class
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.setSuperclass(proxySuperClass);
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);
//生成代理类并创建代理实例
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);
}
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
//对于expose-proxy属性的处理
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
//将拦截器封装在DynamicAdvisedInterceptor
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // 将拦截器加入Callback中
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimisations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimisation here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
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 {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
1.4 静态AOP使用示例
未完待续. . .