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?
相關文章
相關標籤/搜索