博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring AOP动态代理-切面
阅读量:6841 次
发布时间:2019-06-26

本文共 3999 字,大约阅读时间需要 13 分钟。

hot3.png

在上一节中,我们通过Advice可以对目标类进行增强,使得目标类在调用的时候可以执行增强类中的代码,但是,增强类适配了目标类中的所有方法。如果我们只需要对目标类中的部分方法使用增强类,该如何操作呢?比如我们上一节的场景:乘客乘坐火车,在上车之前需要检票,在这一节中我们继续添加一项业务:旅客服务。 相关代码:

public interface TakingTrain {	public void takeTrain(String name) throws RestException;	public void customSerive(String name);}//接口的实现public void customSerive(String name) {		System.out.println("Hi, "+name+" ,may i help you?");	}

修改我们的测试类代码: 添加:proxy.customSerive("LaoWang");

@Test	public void testAdivice(){		ProxyFactory factory = new ProxyFactory();		TakingTrain trainImpl  = new TakingTrainImpl();		factory.setInterfaces(trainImpl.getClass().getInterfaces());		factory.setTarget(trainImpl);		factory.addAdvice(new CheckTicketAdvice());		TakingTrain proxy = (TakingTrain) factory.getProxy();		try {			proxy.takeTrain("LaoWang");			proxy.customSerive("LaoWang");		} catch (RestException e) {		}	}

打印结果:

please show your tickesHi LaoWang Welcome to take the trainplease show your tickesHi, LaoWang ,may i help you?

这个时候我们发现 please show your tickes这句话打印了两遍。也就是说CheckTicketAdvice中的方法执行了两遍。这可不是我们想要的结果。 而我们现在需要的是对TakingTrain 中的 takeTrain 方法之前调用。而不是所有的方法都调用。 用什么方法可以实现这个功能呢?AOP!它可以通过切面讲增强类有选择的织入到目标类的特定方法中。 换句话说,我们需要两个功能:

  • 拦截类:ClassFilter 输入图片说明

  • 拦截方法:MethodMatcher 输入图片说明

相关的类图 输入图片说明

具体实现(使用静态方法匹配切面):

1.定义切面,在切面内可进行类级别和方法级别的拦截。 注意,将切点设置到切面内:

public class StaticMethodCheckTicketAdvisor extends StaticMethodMatcherPointcutAdvisor{	public StaticMethodCheckTicketAdvisor(Advice advice) {		this.setAdvice(advice);	}	@Override	public boolean matches(Method method, Class
targetClass) { return "takeTrain".equals(method.getName()); }}

2.切点保持不变:

public class CheckTicketAdvice implements MethodBeforeAdvice{	@Override	public void before(Method method, Object[] args, Object target)			throws Throwable {		System.out.println("please show your tickes");	}}

3.实现类:

@Test	public void testStaticMethodAdvisor(){		ProxyFactory factory = new ProxyFactory();		StaticMethodCheckTicketAdvisor advisor = new StaticMethodCheckTicketAdvisor(new CheckTicketAdvice());		TakingTrain trainImpl  = new TakingTrainImpl();		factory.setInterfaces(trainImpl.getClass().getInterfaces());		factory.setTarget(trainImpl);		factory.addAdvisor(advisor);		TakingTrain proxy = (TakingTrain) factory.getProxy();		try {			proxy.takeTrain("LaoWang");			proxy.customSerive("LaoWang");		} catch (RestException e) {		}	}

4.打印结果:

please show your tickesHi LaoWang Welcome to take the trainHi, LaoWang ,may i help you?

具体实现(使用表达式匹配切面):

1.定义切面,在切面内可进行类级别和方法级别的拦截。 注意,将切点,以及表达式设置到切面内:

public class RegexpMethodCheckTicketAdvisor extends RegexpMethodPointcutAdvisor{	public RegexpMethodCheckTicketAdvisor() {		super();		// TODO Auto-generated constructor stub	}	public RegexpMethodCheckTicketAdvisor(Advice advice) {		super(advice);		// TODO Auto-generated constructor stub	}	public RegexpMethodCheckTicketAdvisor(String pattern, Advice advice) {		super(pattern, advice);		// TODO Auto-generated constructor stub	}	public RegexpMethodCheckTicketAdvisor(String[] patterns, Advice advice) {		super(patterns, advice);		// TODO Auto-generated constructor stub	}	}

2.切点保持不变:

public class CheckTicketAdvice implements MethodBeforeAdvice{	@Override	public void before(Method method, Object[] args, Object target)			throws Throwable {		System.out.println("please show your tickes");	}}

3.实现类:

@Test	public void testRegexpMethodAdvisor(){		ProxyFactory factory = new ProxyFactory();		RegexpMethodCheckTicketAdvisor advisor = new RegexpMethodCheckTicketAdvisor();		advisor.setPattern(".*takeTrain.*");		advisor.setAdvice(new CheckTicketAdvice());		TakingTrain trainImpl  = new TakingTrainImpl();		factory.setInterfaces(trainImpl.getClass().getInterfaces());		factory.setTarget(trainImpl);		factory.addAdvisor(advisor);		TakingTrain proxy = (TakingTrain) factory.getProxy();		try {			proxy.takeTrain("LaoWang");			proxy.customSerive("LaoWang");		} catch (RestException e) {		}	}

4.打印结果:

please show your tickesHi LaoWang Welcome to take the trainHi, LaoWang ,may i help you?

转载于:https://my.oschina.net/lfy2008/blog/685979

你可能感兴趣的文章
我的友情链接
查看>>
MongoDB 安装以及系统服务配置方法
查看>>
RAID 技术介绍
查看>>
ldap linux client详细配置
查看>>
【华为OJ】逆波兰
查看>>
通过shell导出数据库查询结果到excel中,并通过邮件发送到邮箱
查看>>
8 个你可能不知道的 Docker 知识
查看>>
JavaSE学习笔记(六)——类的继承
查看>>
java代码编写出现的陷阱-2:阴沟里翻船
查看>>
CentOS Zabbix Server安装
查看>>
Redis sort命令详解
查看>>
Linux Top 命令详解
查看>>
Don't be too serious about knowing the world
查看>>
servlet,RMI,webservice之间的区别
查看>>
Java异常架构
查看>>
Git 分支合并冲突及合并分类
查看>>
解决UnicodeEncodeError: 'ascii' codec can't encode characters in position
查看>>
Android开机广播android.intent.action.BOOT_COMPLETED
查看>>
Linux服务器信息收集
查看>>
怎样在 CentOS 7.0 上安装和配置 VNC 服务器
查看>>