Spring之AOP之底层实现
静态代理实现
- 定义IStudnetService接口
/**
* IStudentService的接口
* @author chenjiabing
*/
public interface IStudentService {
void add();
}
- 定义StudentServiceImpl实现方法
@Service
public class StudentServiceImpl implements IStudentService {
public void add() {
System.out.println("StudentService的add方法");
}
}
- 定义StudentAop切面类
/**
* 切面类
* @author chenjiabing
*/
@Component
public class StudentAOP {
//之前执行
public void before(){
System.out.println("StudentAOP.before....");
}
//之后执行
public void after(){
System.out.println("StudentAOP.after");
}
//在之后执行,只在没有出现异常的时候执行
public void afterReturning(){
System.out.println("StudentAOP.afterReturning");
}
//之后执行,但是只在出现异常的时候执行
public void afterThrowing(){
System.out.println("StudentAOP.throwing");
}
//环绕方法
public void arounding(){
System.out.println("StudentAOP.arounding");
}
}
- 定义StudentProxy代理类
/**
* 静态代理类
* @author chenjiabing
*/
@Component
public class StudentProxy implements IStudentService {
@Resource
private StudentAOP studentAOP; //依赖注入切面对象
@Resource
private IStudentService studentService; //目标对象
public void add() {
try {
studentAOP.arounding(); //执行环绕方法
studentAOP.before(); //执行切面类的方法
studentService.add(); //执行目标对象的方法
studentAOP.after(); //执行切面的after方法
studentAOP.afterReturning(); //执行切面类afterReturning的方法
} catch (Exception e) {
studentAOP.afterThrowing(); //执行切面类的方法,在出现异常之后执行
}finally{
studentAOP.arounding(); //执行环绕方法
}
}
}
- 测试方法
@Test
public void test1() {
// 加载Spring的配置文件
AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
"spring-dao.xml", "spring-service.xml","spring-aop.xml");
//创建Service,其中使用的是动态代理类
IStudentService studentService=ac.getBean("studentProxy",IStudentService.class);
studentService.add();
}
动态代理实现
代理类实现java.lang.reflect.InvocationHandler接口
/**
* 动态代理的类
*
* @author chenjiabing
*/
@Component // 创建对象
public class ProxyHandler implements InvocationHandler {
private Object object; // 目标对象
@Resource
private StudentAOP studentAOP; // 注入切面类
// 获取动态代理类的对象
public Object getObject(Object object){
this.object=object;
/**
* 第一个参数:目标类的类加载器
* 第二个参数:目标类的接口
* 第三个参数:动态代理的实例
*/
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
/**
* @param proxy :被代理的对象
* @param method : 要调用的方法
* @param args : 方法调用的时候所需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
studentAOP.before(); //调用切面的before方法
//通过反射调用目标类的方法
Object result=method.invoke(object, args); //调用目标类的方法
studentAOP.after(); //调用切面的after方法
return result;
}
}
- 测试方法
@Test
public void test2() {
// 加载Spring的配置文件
AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
"spring-dao.xml", "spring-service.xml","spring-aop.xml");
//获取动态代理类的对象
ProxyHandler proxyHandler=ac.getBean("proxyHandler",ProxyHandler.class);
//获取代理类的对象
IStudentService studentService=(IStudentService) proxyHandler.getObject(new StudentServiceImpl());
studentService.add();
}
网友评论