前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring之AOP之底层实现

Spring之AOP之底层实现

作者头像
爱撒谎的男孩
发布2019-12-31 15:04:39
2780
发布2019-12-31 15:04:39
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

文章目录

  1. 1. Spring之AOP之底层实现
    1. 1.1. 静态代理实现
    2. 1.2. 动态代理实现
    3. 1.3. 参考文档

Spring之AOP之底层实现

静态代理实现

  • 定义IStudnetService接口
代码语言:javascript
复制
/**
 * IStudentService的接口
 * @author chenjiabing
 */
public interface IStudentService {

	void add();
}
  • 定义StudentServiceImpl实现方法
代码语言:javascript
复制
@Service
public class StudentServiceImpl implements IStudentService {

	public void add() {
		System.out.println("StudentService的add方法");
	}
}
  • 定义StudentAop切面类
代码语言:javascript
复制
/**
 * 切面类
 * @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代理类
代码语言:javascript
复制
/**
 * 静态代理类
 * @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();  //执行环绕方法
		}
	}
}
  • 测试方法
代码语言:javascript
复制
@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接口
代码语言:javascript
复制
/**
 * 动态代理的类
 * 
 * @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;
	}

}
  • 测试方法
代码语言:javascript
复制
@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();
	
}

参考文档

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring之AOP之底层实现
    • 静态代理实现
      • 动态代理实现
        • 参考文档
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档