Spring AOP动态代理-切面

在上一节中,咱们经过Advice能够对目标类进行加强,使得目标类在调用的时候能够执行加强类中的代码,可是,加强类适配了目标类中的全部方法。若是咱们只须要对目标类中的部分方法使用加强类,该如何操做呢?好比咱们上一节的场景:乘客乘坐火车,在上车以前须要检票,在这一节中咱们继续添加一项业务:旅客服务。 相关代码:ide

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) {

		}
	}

打印结果:this

please show your tickes
Hi LaoWang Welcome to take the train
please show your tickes
Hi, LaoWang ,may i help you?

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

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

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

相关的类图 输入图片说明get

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

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

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.切点保持不变:class

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 tickes
Hi LaoWang Welcome to take the train
Hi, 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 tickes
Hi LaoWang Welcome to take the train
Hi, LaoWang ,may i help you?
相关文章
相关标签/搜索