AOP
切点:确定的方法点
前置通知:切点执行之前要执行的代码
后置通知:切点执行之后要执行的代码
切面:前置+切点+后置行程的面
织入:添加通知的过程
复制代码
通知类型
前置通知
后置通知
环绕通知
异常通知
返回后通知
复制代码
实现方式
schema-based:必须自己写通知类,实现方法
aspectj:不需要程序员自己写通知类
复制代码
schema-base实现AOP
步骤:
-
导包 aopalliance-1.0.jar 处理Aop相关的
aspectjrt-1.8.10.jar aspectj包
aspectjweaver-1.8.10.jar
-
写通知类
public class AfterMethodAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object object, Method method, Object[] args, Object arg3) throws Throwable {
/*
* 参数1:切点方法的返回值
* 参数2:切点方法
* 参数3:切点方法的参数
* 参数4:调用切点方法的对象
*/
System.out.println("提交事务");
}
}
复制代码
public class BeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method mehtod, Object[] args, Object object) throws Throwable {
/*
* 参数1:切点方法,要添加前置通知的方法
* 参数2:切点方法的参数
* 参数3:切点方法在哪个对象里面,调用该切点方法的对象
*/
System.out.println("开启事务");
}
}
复制代码
-
导入spring的主配置文件,导入aop的命名空间、约束条件 在xmlns:context=...复制,将其后缀context给aop 复制http://context后缀的两条http,将其中context全部改为aop
-
配置AOP
<!-- 1. 配置AOP --> <aop:config> <!-- 1.1配置切点:找到要添加通知的方法(代理是一个类的所有方法) 通过切入点表达式找到对应的方法 id:切点的id --> <aop:pointcut expression="execution(* com.dyr.aop.StudentDao.insert())" id="pt"/> <!-- 2.2配置通知 --> <aop:advisor advice-ref="before" pointcut-ref="pt"/> <aop:advisor advice-ref="after" pointcut-ref="pt"/> </aop:config> <!-- 2.配置通知 --> <bean id="before" class="com.dyr.aop.BeforeAdvice"></bean> <bean id="after" class="com.dyr.aop.AfterMethodAdvice"></bean> <!-- 配置要添加通知的类 --> <bean id="studentDao" class="com.dyr.aop.StudentDao"></bean> 复制代码
5.测试
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("application-context.xml"); StudentDao dao = ac.getBean(StudentDao.class); dao.insert(); } 复制代码
结果
开启事务 向数据库中添加一条记录 提交事务 复制代码
aspectj:实现AOP(注解方式)
1. 文档结构
Aspectj.java 测试
DogImpl.java dao层,添加注解@Repository("dao"),加入IOC容器
DogService.java 添加注解@Service("service"),属性dao添加注解@Resource(name="dao")
IDog.java : dao层,service层均实现该接口,提供抽象方法,dao层具体实现,service方法调用dao层的同名方法。
PointCut.java :将切面相关的都放入这个类中。共三个方法
复制代码
@Component //jiangdangqianneijiaruIOCrongqi
@Aspect //dangzuo qiemianlei
public class PointCut {
//配置切点
@Pointcut("execution(* com.dyr.aspectj.DogService.update())")
public void pointcut() {
}
//前置通知注意小括号
@Before("pointcut()")
public void beafore() {
System.out.println("开启事务");
}
//后置通知
@After("pointcut()")
public void after() {
System.out.println("提交事务");
}
}
复制代码
- 主配置文件配置:
<!-- 开启扫描 --> <context:component-scan base-package="com.dyr.aspectj"></context:component-scan> <!-- 开启AOP注解 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 复制代码
aspectj:实现AOP(注解方式)
- 文档结构 Aspectj.java Base.java DogImpl.java DogService.java IDog.java PointCut.java
- 主文件配置
<!-- 1.dao --> <bean id="dao" class="com.woniuxy.aspectjxml.DogImpl"></bean> <!-- 2.service --> <bean id="service" class="com.woniuxy.aspectjxml.DogService"> <property name="dao" ref="dao"></property> </bean> <!-- 3.切面类 --> <bean id="pointcut" class="com.woniuxy.aspectjxml.PointCut"></bean> <!-- 4.配置AOP --> <aop:config> <!-- 配置切入点表达式 --> <aop:pointcut expression="execution(* com.woniuxy.aspectjxml.DogService.update()) and execution(* com.woniuxy.aspectjxml.DogService.delete())" id="pt"/> <!-- 配置切面 --> <aop:aspect ref="pointcut"> <aop:before method="before" pointcut-ref="pt"/> <aop:after method="after" pointcut-ref="pt"/> </aop:aspect> </aop:config> 复制代码