Spring AOP源码篇二之 代理工厂ProxyFactory学习

了解AspectJ表达式以及PointCut、Advice、Advisor后,继续学习Spring AOP代理工厂
AspectJ表达式参考:Spring AOP之AspectJ表达式-优快云博客
PointCut、Advice、Advisor参考:Spring AOP源码篇一之 PointCut、Advice、Advisor学习-优快云博客
简单代码示例:
package org.spring.aop.proxy.service;

public interface IUserService {
    void say();
}
package org.spring.aop.proxy.service;

public class UserService implements IUserService {
    public void say() {
        System.out.println("Hello world!!");
    }
}
package org.spring.aop.proxy.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LogAdvice implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		System.out.println("===============log record start==============");
		Object object = methodInvocation.proceed();
		System.out.println("===============log record end================");
		return object;
	}
}

测试代码:

package org.spring.aop.proxy;

import org.spring.aop.proxy.advice.LogAdvice;
import org.spring.aop.proxy.service.IUserService;
import org.spring.aop.proxy.service.UserService;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class ProxyFactoryTest {
    public static void main(String[] args) {
        System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        IUserService service = new UserService();
        ProxyFactory proxyFactory = new ProxyFactory(service);
        IUserService serviceProxy = (IUserService) proxyFactory.getProxy();
        //不打印toString是因为代理对象底层toString调的是目标对象的toString,二者toString内容一样。
        System.out.printf("原始对象[%s]====代理对象[%s]====[比较二者:%s]\n", service.hashCode(), serviceProxy.hashCode(), (service == serviceProxy));
        serviceProxy.say();

        System.out.println("\n-------------对目标对象增强功能-----------------\n");
        String expression = "execution(* org.spring.aop.proxy.service.UserService.*(..))";
        Advisor advisor = buildAdvisor(expression);
        proxyFactory.addAdvisor(advisor);
        serviceProxy = (IUserService) proxyFactory.getProxy();
        serviceProxy.say();
    }

    public static Advisor buildAdvisor(String expression) {
        //创建pointcut
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(expression);

        //创建advice
        LogAdvice advice = new LogAdvice();

        //创建advisor
        Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);

        return advisor;
    }
}

执行结果:

代理工厂ProxyFactory继承体系

Advised是个配置管理类,对Advisor、Advice进行配置管理
package org.springframework.aop.framework;

import org.aopalliance.aop.Advice;

import org.springframework.aop.Advisor;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopConfigException;

public interface Advised extends TargetClassAware {

	/**
	 * 判断advised配置是否冻结
	 * 一旦冻结,不允许删除或增加Advisor和Adivce
	 */
	boolean isFrozen();

	/**
	 * 判断是否直接代理目标类,而不是目标类的父接口
	 * Spring中代理分为JDK动态代理、CGLIB代理;JDK动态代理的是父接口,CGLIB代理的是目标类(具体类)
	 */
	boolean isProxyTargetClass();

	/**
	 * 返回目标对象的父接口,如果目标对象类型是接口则包含其中,如果不是接口则不包含其中。
	 * 如果advice是引介增强的话,advice的接口也会放入其中。
	 */
	Class<?>[] getProxiedInterfaces();

	/**
	 * 判断指定的接口是否已被代理(被代理的接口一般是目标类的父接口,
	 * 默认Spring Aop会为目标对象的代理对象额外添加两个父接口SpringProxy、Advised)
	 */
	boolean isInterfaceProxied(Class<?> intf);


	/*
		/*public interface TargetSource extends TargetClassAware {
			/**
			 * 返回目标对象类型
			 *//*
			Class<?> getTargetClass();

			*//**
			 * 判断目标对象是否为静态
			 *//*
			boolean isStatic();

			*//**
			 * 返回目标对象
			 *//*
			Object getTarget() throws Exception;

			*//**
			 * 释放销毁目标对象(spring中该方法基本都是空实现),getTarget()时重新创建
			 *//*
			void releaseTarget(Object target) throws Exception;
		}
	 */
	/**
	 * 设置被代理的目标对象TargetSource(目标对象被封装在TargetSource)
	 */
	void setTargetSource(TargetSource targetSource);

	/**
	 * 返回被代理目标对象的TargetSource(目标对象被封装在TargetSource中)
	 */
	TargetSource getTargetSource();

	/**
	 * 代理对象是否设置到AOP框架中的ThreadLocal中
	 */
	void setExposeProxy(boolean exposeProxy);

	/**
	 * 判断代理对象是否被设置到了AOP框架中的ThreadLocal中
	 */
	boolean isExposeProxy();

	/**
	 * 设置所有添加的advisor是否已经提前过滤过了(advisor和目标对象已经提前匹配过了)
	 * 也就是所添加advisor的Advice已经是完全可以应用到目标对象上的
	 */
	void setPreFiltered(boolean preFiltered);

	/**
	 * 判断所有添加的advisor是否已经提前过滤过了
	 */
	boolean isPreFiltered();

	/**
	 * 返回Advisor列表
	 */
	Advisor[] getAdvisors();

	/**
	 * 添加Advisor
	 */
	void addAdvisor(Advisor advisor) throws AopConfigException;

	/**
	 * 在指定位置添加Advisor
	 */
	void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

	/**
	 * 删除Advisor,不存在的话不做删除
	 */
	boolean removeAdvisor(Advisor advisor);

	/**
	 * 删除指定位置Advisor,index无效的话会报异常
	 */
	void removeAdvisor(int index) throws AopConfigException;

	/**
	 * 返回advisor位置,不存在返回-1
	 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值