※AOP傳參數、Returning
※之前的before和after都沒有傳參數,現在傳個參數,還有回傳值的接收使用B方法傳參數; D方法接收回傳值
※XML設定
IAOP.java和AOP.java
public interface IAOP { public void B(String s, Book b); public String D(String d); } @Named public class AOP implements IAOP { @Override public void B(String s, Book b) { System.out.println("有參數B"); } @Override public String D(String d) { System.out.println("有參數D"); return d; } }
Book.java
@Component("bo") public class Book { private String bookName; private int bookPrice; // setter/getter... }
BeforeAfter.java
@Named public class BeforeAfter { public void beforeParam(Object o, Book b) { System.out.println("之前+參數,參數是:" + o + "和" + b.getBookName()); } public void afterReturn(String s) { System.out.println("回傳值" + s); } }
applicationContext.xml
<context:component-scan base-package="\" /> <aop:config> <aop:aspect ref="beforeAfter"> <aop:before method="beforeParam" pointcut="execution(public void aop.AOP.B(String, vo.Book)) and args(p1, p2)" arg-names="p1, p2" /> <aop:after-returning method="afterReturn" pointcut="execution(public String aop.AOP.D(String))" returning="r1" arg-names="r1"/> </aop:aspect> </aop:config>
※p1、p2, r1要對應好,Book用包.類,一般的可省略,如:String、int等
測試類
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Book book = new Book(); book.setBookName("七龍珠"); book.setBookPrice(50); IAOP aop = ctx.getBean("AOP", IAOP.class); aop.B("ooo", book); aop.D("ddd"); ((ClassPathXmlApplicationContext) ctx).close();
※結果:
之前+參數,參數是:ooo和七龍珠
有參數B
有參數D
回傳值ddd
※Annotation設定
@Named @Aspect public class BeforeAfter { @Before(value="execution(public void aop.AOP.B(String, vo.Book)) and args(p1, p2)", argNames="p1, p2") public void beforeParam(Object o, Book b) { System.out.println("之前+參數,參數是:" + o + "和" + b.getBookName()); } @AfterReturning(pointcut = "execution(public String aop.AOP.D(String))", returning = "r1", argNames = "r1") public void afterReturn(String s) { System.out.println("回傳值" + s); } }
※Throwing
如果有例外,可以設定抓例外的資訊※XML設定
IAOP.java和AOP.java
public interface IAOP { public void D(String d) throws ArithmeticException; } @Named public class AOP implements IAOP { @Override public void D(String d) { System.out.println("有參數D"); try { int a = 1 / 0; } catch (ArithmeticException e) { throw new ArithmeticException(); } } }
BeforeAfter.java
@Named public class BeforeAfter { public void afterThrow(Exception e) { System.out.println("AOP截取例外:" + e); } }
applicationContext.xml
<context:component-scan base-package="\" /> <aop:config> <aop:aspect ref="beforeAfter"> <aop:after-throwing method="afterThrow" pointcut="execution(public void aop.AOP.D(String))" throwing="t1" arg-names="t1" /> </aop:aspect> </aop:config>
※和回傳值一樣,只不過屬性名稱變成throwing,要和arg-names對應
測試類
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); IAOP aop = ctx.getBean("AOP", IAOP.class); try { aop.D("ddd"); } catch (ArithmeticException e) {} ((ClassPathXmlApplicationContext) ctx).close();
※結果:
有參數D
AOP截取例外:java.lang.ArithmeticException
※注意這個D方法沒有回傳值,但還是可以抓到喔!
※Annotation設定
@Named @Aspect public class BeforeAfter { @AfterThrowing(pointcut = "execution(public void aop.AOP.D(String))", throwing = "t1", argNames = "t1") public void afterThrow(Exception e) { System.out.println("AOP截取例外:" + e); } }
※Around
IAOP.java和AOP.java
public interface IAOP { public String B(String s, Book b); } @Named public class AOP implements IAOP { @Override public String B(String s, Book b) { System.out.println("有參數B"); // try { // int a = 1 / 0; // } catch (Exception e) { // System.out.println("我錯了B"); // } return "參數B回傳"; } }
Book.java
@Component("bo") public class Book { private String bookName; private int bookPrice; // setter/getter... }
BeforeAfter.java
// @Named // @Aspect public class BeforeAfter { // @Around("execution(public String aop.AOP.B(String, vo.Book))") // ProceedingJoinPoint可取得方法資訊 public void around(ProceedingJoinPoint pjp) { System.out.println("around start" + Arrays.toString(pjp.getArgs())); try { // Object rtn = pjp.proceed(); Object rtn = pjp.proceed(new Object[] { "hello String", new Book() }); System.out.println("rtn=" + rtn); } catch (Throwable e) { e.printStackTrace(); } } }
<context:component-scan base-package="\" /> <!-- <aop:aspectj-autoproxy/> --> <aop:config> <aop:aspect ref="beforeAfter"> <aop:around method="around" pointcut="execution(public String aop.AOP.B(String, vo.Book))" /> </aop:aspect> </aop:config>
測試類
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); for (String s : ctx.getBeanDefinitionNames()) { System.out.println(s); } IAOP aop = ctx.getBean("AOP", IAOP.class); Book book = new Book(); book.setBookName("七龍珠"); book.setBookPrice(50); aop.B("ooo", book); ((ClassPathXmlApplicationContext) ctx).close();
※結果:
around start[ooo, vo.Book@3cc2931c]
有參數B
rtn=參數B回傳
※在BeforeAfter.java的proceed()是overloading,就這兩個方法,一開始會先像before一樣先執行,然後要繼續就要使用proceed(),沒加參數會自動幫我們執行,但要加型態和順序就要和B方法的參數一樣,否則會出錯
沒有留言:
張貼留言