Java实现面向切面编程(AOP)

使用动态代理实现AOP

1、添加依赖

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>5.0.11.RELEASE</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.0.11.RELEASE</version>
</dependency>

2、创建一个计算器接口Cal,定义四个方法

计算器接口Cal

 3、创建接口的实现类CalImpl

高耦合的写法,每次打印日志都要手动完成:

高耦合的写法

4、使用动态代理进行优化

上方代码中,日志信息和业务逻辑的耦合性很高,不利于代码的维护。使用AOP可以进行优化,我们可以使用动态代理实现AOP:
给业务代码找一个代理,打印日志信息的工作交给代理来做。这样的话业务代码就只需要关注自身业务即可。
(1)去掉手动输出的日志信息

去掉手动输出的日志信息

(2).代理辅助类的编写和使用(动态代理的核心)

我们创建的并不是所谓的代理类,而是一个可以帮助我们返回代理对象的辅助类,这个辅助类有两个功能

  1. 接收委托对象并依次返回代理对象
  2. 处理代理对象调用方法的过程

创建代理辅助类

 

  1. 值得注意的是:
  • 注意别忘了给委托对象赋值的那一步
  • 创建代理动态代理对象时传入的方法保证了代理类拥有原类的全部功能
  • 调用代理对象的方法时会自动调用invoke方法
    (3)测试

测试动态代理实现AOP

四、使用Spring实现AOP
动态代理实现AOP比较复杂,不易理解。Spring框架对AOP进行了封装,使用Spring框架可以用面向对象的思想实现AOP。Spring框架中不需要创建辅助类,只需要创建一个切面对象,将所有的非业务代码在切面对象中完成即可(但实际上Spring框架底层依然会根据切面类和代理类来生成代理对象。)

1、添加依赖

 

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>5.0.11.RELEASE</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.0.11.RELEASE</version>
</dependency>

 <dependency>
	 <groupId>org.springframework</groupId>
	 <artifactId>spring-context</artifactId>
	 <version>5.0.11.RELEASE</version>
 </dependency>

 

2、创建一个计算器接口Cal,定义四个方法

当使用Spring实现时,这一步非必须!直接在实体类里面定义方法也可

计算器接口

3、定义实体类,实现方法

注意需要加上Component注解把他交给IoC

定义实体类,实现方法

4、创建切面类

创建切面类

类定义处的两个注解

  • @Aspect表示该类是一个切面类
  • @Component将该类的对象注入到IoC容器(切面类和实体类都需要加上这个注解)

方法处的注解

  • @Before表示方法执行的具体位置和时机是方法开始时

  • @After类似Before,不过位置是方法的最后

 在这里插入图片描述

  • @AfterReturning在下文有作解释

  • @AfterThrowing在下文有作解释

 5、在spring.xml中进行配置

Spring配置文件

  • context:component-scan指扫描com.pedro包中的所有类,如果该类同时添加了component注解,则将该类扫描IoC容器中。即IoC管理它的对象
  • aop:aspectj-autoproxy让Spring容器结合切面类和目标类自动生成代理对象

6、使用

使用Spring的AOP

用代理对象调用方法就会自动执行它本身的方法和切面类中的非业务代码

为什么类名首字母要小写?
当使用注解配置bean时,默认id(别名)就是首字母改为小写的类名。若想修改,就在实体类的注解处加上自定义的名字即可。如@Component("test"),这样的话在getBean的时候就可以使用自定义的别名了,即xx.getBean("test")

7、两个特殊的After注解
(1)AfterReturning

用于在获取返回值后执行一段非业务代码

AfterReturning

(2)AfterThrowing

切面类的AfterThrowing注解,用于在抛出异常后执行一段非业务代码

AfterThrowing

 

 

 

 

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值