部分代码取自百度文库
Spring AOP底层涉及到的知识点:JAVA反射机制,代理模式,以及CGLB库的使用。也就是说,Spring AOP底层实现就是靠动态代理(针对有接口的类)和CGLIB(针对没有接口的一般类)。
最简单的AOP实现只需要涉及3个概念:目标(Target),通知(Advice)和代理(Proxy)。
目标:真实的需要被代理的对象,一般它会实现至少一个接口。
通知:当目标的方法调用时需要调用的代码,也叫拦截器。
代理:加入了通知的目标,可以作为目标的替身出现。
一段自己练习的代码:
接口部分:
package com.koubei.springtest.SpringTest.aop2;
public interface BuyBook {
public void buyBook(String customer,String book)throws NOThisBookException;
}
实现部分
package com.koubei.springtest.SpringTest.aop2;
public class MyBuyBook implements BuyBook {
public void buyBook(String customer, String book) throws NOThisBookException {
if(book.equals("<hibernate in action>")){
throw new NOThisBookException("对不起,没有"+book+"的存货了!");
}
System.out.println(customer+",你好,你已经购买了一本"+book+"!");
}
}
异常的申明:
package com.koubei.springtest.SpringTest.aop2;
public class NOThisBookException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public NOThisBookException(String msg){
super(msg);
}
}
异常定义:
package com.koubei.springtest.SpringTest.aop2;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method method,Object[] args,Object target,NOThisBookException e){
System.out.println("对不起"+args[0]+",没有货了,通知仓库,赶紧加书");
}
}
前置定义
package com.koubei.springtest.SpringTest.aop2;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
//第二个参数组就是被通知的方法传入的参数,本例中即customer,book
String customer = (String) args[0];
//显示欢迎信息,在buyBook方法前调用
System.out.println("欢迎您"+customer+"!");;
}
}
后置定义:
package com.koubei.springtest.SpringTest.aop2;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method,Object[] args, Object target) throws Throwable {
String customer = (String) args[0];
System.out.println("再见,希望你再来"+customer+"!");
}
}
环绕定义:
package com.koubei.springtest.SpringTest.aop2;
import java.util.HashSet;
import java.util.Set;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor {
private Set<Object> customers = new HashSet<Object>();
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
Object[] args = arg0.getArguments();
if(customers.contains(args[0])){
System.out.println("对不起,一名顾客只能买一本打折书");
return null;
}
customers.add(args[0]);
return arg0.proceed();
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 前置通知 -->
<bean id="myBeforeAdvice" class="com.koubei.springtest.SpringTest.aop2.MyBeforeAdvice"/>
<!-- 后置通知 -->
<bean id="myAfterAdvice" class="com.koubei.springtest.SpringTest.aop2.MyAfterAdvice"/>
<!-- 异常通知 -->
<bean id="myThrowsAdvice" class="com.koubei.springtest.SpringTest.aop2.MyThrowsAdvice"/>
<!-- 环绕通知 -->
<bean id="myAroundAdvice" class="com.koubei.springtest.SpringTest.aop2.MyAroundAdvice"/>
<!-- 目标对象 -->
<bean id="buyBookTarget" class="com.koubei.springtest.SpringTest.aop2.MyBuyBook"/>
<!-- 代理对象 -->
<bean id="buyBook" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 实现的接口 -->
<property name="proxyInterfaces">
<value>com.koubei.springtest.SpringTest.aop2.BuyBook</value>
</property>
<!-- 应用所有拦截器对象 -->
<property name="interceptorNames">
<list>
<value>myBeforeAdvice</value>
<value>myAfterAdvice</value>
<value>myThrowsAdvice</value>
<value>myAroundAdvice</value>
</list>
</property>
<property name="target">
<ref bean="buyBookTarget"/>
</property>
</bean>
</beans>
测试类:
package com.koubei.springtest.SpringTest;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BuyBook ps = (BuyBook ) ctx.getBean("buyBook");
ps.save();
}
}