※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方法的參數一樣,否則會出錯
沒有留言:
張貼留言