千家信息网

怎么实现Spring Core动态代理

发表于:2024-11-20 作者:千家信息网编辑
千家信息网最后更新 2024年11月20日,本篇内容主要讲解"怎么实现Spring Core动态代理",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么实现Spring Core动态代理"吧!目录1.
千家信息网最后更新 2024年11月20日怎么实现Spring Core动态代理

本篇内容主要讲解"怎么实现Spring Core动态代理",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么实现Spring Core动态代理"吧!

目录
  • 1.设计原理

  • 2.ProxyFactory (Spring-Core)

    • 2.1 JdkDynamicAopProxy

    • 2.2 CglibAopProxy

    • 2.3 主要源码部分

1.设计原理

通过JDK的Proxy方式或者CGLIB方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了;
通过拦截器回调

JDK动态代理:代理类和目标类实现了共同的接口,用到InvocationHandler接口。(见下面代码)
CGLIB动态代理:代理类是目标类的子类,用到MethodInterceptor接口。(见下面代码)

jdk动态代理是由Java内部的反射机制来实现的;
cglib动态代理底层则是借助asm来实现的。

jdk (Proxy)

使用了Proxy类的newProxyInstance()方法来创建代理对象

final UserService target=new UserServiceImpl();        Class clazz = UserService.class;        ClassLoader loader = clazz.getClassLoader();        Object proxyInstance = Proxy.newProxyInstance(loader, new Class[]{clazz}, new InvocationHandler() {            @Override            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;            }        });        UserService service = (UserService) proxyInstance;        service.getUserInfo();

cglib

动态类对象Enhancer,它是CGLIB的核心类;Enhancer类的setSuperclass()方法来确定目标对象;setCallback()方法添加回调函数。最后通过return 语句将创建的代理类对象返回。intercept()方法会在程序执行目标方法时被调用,方法运行时会执行切面类中的增强方法(前和后)。

Enhancer enhancer=new Enhancer();        enhancer.setSuperclass(UserInfo.class);        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {            @Override            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {                System.out.println("Before...");                Object result = methodProxy.invokeSuper(o, objects);                System.out.println("After...");                return result;            }        }});        UserInfo userInfo = (UserInfo) enhancer.create();        userInfo.test();

2.ProxyFactory (Spring-Core)

ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术;
getProxy() 返回 CglibAopProxy 或者 JdkDynamicAopProxy

UserService target=new UserServiceImpl();        ProxyFactory proxyFactory=new ProxyFactory();        proxyFactory.setTarget(target);        //addAdvice() 添加多个,自动形成责任链        proxyFactory.addAdvice(new AopMethodAroundAdvice());        proxyFactory.addAdvice(new AopMethodBeforeAdvice());        proxyFactory.addAdvice(new AopMethodAfterAdvice());        proxyFactory.addAdvice(new AopMethodThrowsAdvice());                //Advisor 设置具体 pointCut和  advice//        proxyFactory.addAdvisor(new AopPointcutAdvisor());        UserService userService = (UserService) proxyFactory.getProxy();        userService.getUserInfo();        userService.test();
public Object getProxy() {                return createAopProxy().getProxy();        }

2.1 JdkDynamicAopProxy

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {        @Override        public Object getProxy() {                return getProxy(ClassUtils.getDefaultClassLoader());        }        @Override        public Object getProxy(@Nullable ClassLoader classLoader) {                if (logger.isTraceEnabled()) {                        logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());                }                return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);        }        @Override        @Nullable        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                                                ...省略...                        Object retVal;                        if (this.advised.exposeProxy) {                                // Make invocation available if necessary.                                oldProxy = AopContext.setCurrentProxy(proxy);                                setProxyContext = true;                        }                        // Get as late as possible to minimize the time we "own" the target,                        // in case it comes from a pool.                        target = targetSource.getTarget();                        Class targetClass = (target != null ? target.getClass() : null);                        //重点:获取此方法的拦截链                        List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);                        // Check whether we have any advice. If we don't, we can fallback on direct                        // reflective invocation of the target, and avoid creating a MethodInvocation.                        if (chain.isEmpty()) {                                // We can skip creating a MethodInvocation: just invoke the target directly                                // Note that the final invoker must be an InvokerInterceptor so we know it does                                // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.                                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);                                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);                        }                        else {                                // We need to create a method invocation...                                MethodInvocation invocation =                                                new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);                                // Proceed to the joinpoint through the interceptor chain.                                retVal = invocation.proceed();                        }                        // Massage return value if necessary.                        Class returnType = method.getReturnType();                        if (retVal != null && retVal == target &&                                        returnType != Object.class && returnType.isInstance(proxy) &&                                        !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {                                // Special case: it returned "this" and the return type of the method                                // is type-compatible. Note that we can't help if the target sets                                // a reference to itself in another returned object.                                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);                        }                }        }

2.2 CglibAopProxy

class CglibAopProxy implements AopProxy, Serializable {        @Override        public Object getProxy() {                return getProxy(null);        }        @Override        public Object getProxy(@Nullable ClassLoader classLoader) {                if (logger.isTraceEnabled()) {                        logger.trace("Creating CGLIB proxy: " + 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 (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {                                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, classLoader);                        // 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 ClassLoaderAwareGeneratorStrategy(classLoader));                        //重点:设置Callbacks[]                        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 | IllegalArgumentException ex) {                        throw new AopConfigException("Could not generate CGLIB subclass of " + 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);                }        }        //获取Callbacks[]        private Callback[] getCallbacks(Class rootClass) throws Exception {                // Parameters used for optimization choices...                boolean exposeProxy = this.advised.isExposeProxy();                boolean isFrozen = this.advised.isFrozen();                boolean isStatic = this.advised.getTargetSource().isStatic();                // Choose an "aop" interceptor (used for AOP calls). (重要类)                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,  // for normal advice                                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;                ...省略...                return callbacks;        }

DynamicAdvisedInterceptor

        private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {                private final AdvisedSupport advised;                public DynamicAdvisedInterceptor(AdvisedSupport advised) {                        this.advised = advised;                }                @Override                @Nullable                public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {                        Object oldProxy = null;                        boolean setProxyContext = false;                        Object target = null;                        TargetSource targetSource = this.advised.getTargetSource();                        try {                                if (this.advised.exposeProxy) {                                        // Make invocation available if necessary.                                        oldProxy = AopContext.setCurrentProxy(proxy);                                        setProxyContext = true;                                }                                // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...                                target = targetSource.getTarget();                                Class targetClass = (target != null ? target.getClass() : null);                                //重点:获取此方法的拦截链                                List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);                                Object retVal;                                // Check whether we only have one InvokerInterceptor: that is,                                // no real advice, but just reflective invocation of the target.                                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {                                        // We can skip creating a MethodInvocation: just invoke the target directly.                                        // Note that the final invoker must be an InvokerInterceptor, so we know                                        // it does nothing but a reflective operation on the target, and no hot                                        // swapping or fancy proxying.                                        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 && !targetSource.isStatic()) {                                        targetSource.releaseTarget(target);                                }                                if (setProxyContext) {                                        // Restore old proxy.                                        AopContext.setCurrentProxy(oldProxy);                                }                        }                }        }

2.3 主要源码部分

public class AdvisedSupport extends ProxyConfig implements Advised {        public List getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class targetClass) {                MethodCacheKey cacheKey = new MethodCacheKey(method);                List cached = this.methodCache.get(cacheKey);                if (cached == null) {                        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(                                        this, method, targetClass);                        this.methodCache.put(cacheKey, cached);                }                return cached;        }

DefaultAdvisorChainFactory

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {        @Override        public List getInterceptorsAndDynamicInterceptionAdvice(                        Advised config, Method method, @Nullable Class targetClass) {                // This is somewhat tricky... We have to process introductions first,                // but we need to preserve order in the ultimate list.                AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();                Advisor[] advisors = config.getAdvisors();                List interceptorList = new ArrayList<>(advisors.length);                Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());                Boolean hasIntroductions = null;                for (Advisor advisor : advisors) {                        if (advisor instanceof PointcutAdvisor) {                                // Add it conditionally.                                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;                                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {                                        MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();                                        boolean match;                                        if (mm instanceof IntroductionAwareMethodMatcher) {                                                if (hasIntroductions == null) {                                                        hasIntroductions = hasMatchingIntroductions(advisors, actualClass);                                                }                                                match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);                                        }                                        else {                                                match = mm.matches(method, actualClass);                                        }                                        if (match) {                                        //重点:将advisor中的advice转换为MethodInterceptor。                                                MethodInterceptor[] interceptors = registry.getInterceptors(advisor);                                                if (mm.isRuntime()) {                                                        // Creating a new object instance in the getInterceptors() method                                                        // isn't a problem as we normally cache created chains.                                                        for (MethodInterceptor interceptor : interceptors) {                                                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));                                                        }                                                }                                                else {                                                        interceptorList.addAll(Arrays.asList(interceptors));                                                }                                        }                                }                        }                        else if (advisor instanceof IntroductionAdvisor) {                                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;                                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {                                        Interceptor[] interceptors = registry.getInterceptors(advisor);                                        interceptorList.addAll(Arrays.asList(interceptors));                                }                        }                        else {                                Interceptor[] interceptors = registry.getInterceptors(advisor);                                interceptorList.addAll(Arrays.asList(interceptors));                        }                }                return interceptorList;        }

DefaultAdvisorAdapterRegistry

构造方法注册了 MethodBeforeAdviceAdapterAfterReturningAdviceAdapterThrowsAdviceAdapter 3个Adapter模板
通过getInterceptors(Advisor advisor) 方法,将 Advisor 总的advice 转换成 MethodInterceptor

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {        private final List adapters = new ArrayList<>(3);        /**         * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.         */        public DefaultAdvisorAdapterRegistry() {                registerAdvisorAdapter(new MethodBeforeAdviceAdapter());                registerAdvisorAdapter(new AfterReturningAdviceAdapter());                registerAdvisorAdapter(new ThrowsAdviceAdapter());        }...省略...        @Override        public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {                List interceptors = new ArrayList<>(3);                Advice advice = advisor.getAdvice();                if (advice instanceof MethodInterceptor) {                        interceptors.add((MethodInterceptor) advice);                }                for (AdvisorAdapter adapter : this.adapters) {                        if (adapter.supportsAdvice(advice)) {                                interceptors.add(adapter.getInterceptor(advisor));                        }                }                if (interceptors.isEmpty()) {                        throw new UnknownAdviceTypeException(advisor.getAdvice());                }                return interceptors.toArray(new MethodInterceptor[0]);        }        @Override        public void registerAdvisorAdapter(AdvisorAdapter adapter) {                this.adapters.add(adapter);        }}

1.AfterReturningAdviceAdapter 通过getInterceptor方法 获取 AfterReturningAdviceInterceptor 过滤器
2. AfterReturningAdviceInterceptor invoke()方法 先执行目标方法,后执行(后置)advice了方法

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {        @Override        public boolean supportsAdvice(Advice advice) {                return (advice instanceof AfterReturningAdvice);        }        @Override        public MethodInterceptor getInterceptor(Advisor advisor) {                AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();                return new AfterReturningAdviceInterceptor(advice);        }}public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {        private final AfterReturningAdvice advice;        /**         * Create a new AfterReturningAdviceInterceptor for the given advice.         * @param advice the AfterReturningAdvice to wrap         */        public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {                Assert.notNull(advice, "Advice must not be null");                this.advice = advice;        }        @Override        @Nullable        public Object invoke(MethodInvocation mi) throws Throwable {                Object retVal = mi.proceed();                this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());                return retVal;        }}

到此,相信大家对"怎么实现Spring Core动态代理"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0