一、AOP 概述
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
有以下程序:
1 、创建一个接口
public interface ProductDao {
public void save();
public void update();
public void find();
public void delete();
}
2、创建一个实现类
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("保存商品成功!");
}
@Override
public void update() {
System.out.println("更新商品成功!");
}
@Override
public void find() {
System.out.println("查询商品成功!");
}
@Override
public void delete() {
System.out.println("删除商品成功!");
}
}
3 、编写测试类
package czm.spring.aop.demo;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ProductTestDemo {
//注入Dao
@Resource(name="productDao")
private ProductDao productDao;
@Test
public void demo(){
productDao.save();
productDao.update();
productDao.find();
productDao.delete();
}
}
程序运行结果:
当后期代码维护需要在save()方法之前插入一个方法,就需要在接口和实现类中新增加一个方法。当有很多个实现类都需要再增加方法,都需要大量修改源代码,不易于后期维护
应用AOP思想就可以在不修改源代码的情况下,在需要的位置切入一个方法,底层实现原理就是在IOC环境下,Spring生成代理对象,代理对象除了拥有具体实现类的方法外还有我们通过xml配置切入的方法
首先编写一个切面类AOPDemo.java,定义要切入的方法 addTest()
/**
* 切面类
* @author ASUS
*
*/
public class AOPDemo {
public void addTest(){
System.out.println("这是切面类的方法!");
}
}
应用AOP前提是在IOC环境下,将ProductDaoImpl 实现类和切面类AOPDemo 均交给Spring管理,并且定义从哪来切入方法
在xml配置文件中配置 :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置目标类================ -->
<bean id="productDao" class="czm.spring.aop.demo.ProductDaoImpl"></bean>
<!-- 配置切面类================ -->
<bean id="AOPDemo" class="czm.spring.aop.demo.AOPDemo"> </bean>
<!-- 配置AOP,完成对目标类产生代理 -->
<aop:config>
<!-- expression 表达式配置哪些类的哪些方法需要进行增强 -->
<!-- 表达式 *号表示任意返回值 , 对ProductDaoImpl类的 save 方法进行增强 , ..表示任意参数-->
<aop:pointcut expression="execution(* czm.spring.aop.demo.ProductDaoImpl.save(..))" id="pointcut"/>
<!-- 配置切面类 -->
<aop:aspect ref="AOPDemo">
<!-- before 表示在ProductDaoImpl类的save()方法之前先执行AOPDemo切面类中addTest()方法 -->
<aop:before method="addTest" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
配置文件中的关系
配置完成后运行原程序
package czm.spring.aop.demo;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ProductTestDemo {
//注入Dao
@Resource(name="productDao")
private ProductDao productDao;
@Test
public void demo(){
productDao.save();
productDao.update();
productDao.find();
productDao.delete();
}
}
程序运行结果:
可以发现在save()方法之前先执行切面类的方法