什么是AOP?
1.AOP概念介绍
所谓AOP就是面向切面编程。
功能: 让重复代码与核心业务分离!
aop的好处:
不用写几遍重复代码,写一次就够了。 开发者只需要关注核心业务; 运行时期,执行核心业务代码时候动态植入需要的代码;aop就采用了动态代理模式。
面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。
切入点(拦截的作用)
执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。
首先要导入依赖
org.aspectj
aspectjweaver
1.9.5
三种方式
test类:
public class UserService1 implements UserService {
public void add(){
System.out.println("UserService1实现了add");
}
public void delete(){
System.out.println("UserService1实现了delete");
}
}
java代码:
//后置日志类
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了"+method.getName()+"方法,结果为"+returnValue);
}
}
java代码:
//前置日志类
public class Log implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(method.getClass().getName()+"的"+method.getName()+"被执行了");
}
}
然后在执行UserService1的时候就会输出结果
第二种(自定义类切入):
xml配置
自定义类:
public class PoinCut {
public void before(){
System.out.println("方法执行前");
}
public void after1(){
System.out.println("方法执行后");
}
}
输出结果:
第三种:使用注解
首先开启注解支持:
xml配置
java代码:
@Aspect //标注这是一个切面
@Component//和xml里注册一个bean效果一样
public class PCut {
@Before("execution(* *..UserService1.*(..))")
public void before(){
System.out.println("========执行前============");
}
/*
* 环绕通知
* 当我们配置了环绕通知之后,切入点方法没有执行,而通知方法执行了
* 分析:
* 通过对比动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法嗲,而我们的代码中没有
* 解决:
* spring框架为我们提供了一个接口,ProceedingJoinPoint,该接口有一个方法proceed(),此方法就相当于明确调用切入点方法,
* 该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类共我们使用
* spring中的环绕通知:
* 他是spring框架为我们提供的一种可以在代码中手动控制的方式
*/
//增强环绕
@Around("execution(* *..UserService1.*(..))")
public void arround(ProceedingJoinPoint pj) throws Throwable {
System.out.println("环绕前");
Object proceed = pj.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}
输出结果:
补充:
spring 中基于XML的AOP配置步骤
1,把通知Bean也交给spring来管理
2,使用aop:config标签表明开始AOP的配置
3,使用aop:aspect标签表明配置切面
id属性:是给切面同一个唯一标识
ref属性:是指定通知类bean的Id
4,在aop:aspect标签的内部使用对应标签中配置同志的类型
我们现在示例是让Spring方法在切入点方法执行之前,所以是前置通知
aop:before:表示配置前置通知
method属性:用于指定Logger类中那个方法是前置通知
pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强
切入点表达式的写法:
关键字:execution(表达式)
表达式:
访问修饰符 返回值 包名.包名.包名...类名..方法名(参数列表)
标准的表达式写法:
public void com.lzh.service.impl.FamilyServiceImpl.saveFamily()
访问修饰符可以省略
void com.lzh.service.impl.FamilyServiceImpl.saveFamily()
返回值可以使用通配符,表示任意返回值
* com.lzh.service.impl.FamilyServiceImpl.saveFamily()
包名可以使用通配符,表示任意包,但是有几级包,就需要写几个
包名可以使用..表示当前包及其子包
* *..FamilyServiceImpl.saveFamily()
类名和方法名都可以使用*来实现通配
* *..*.*() 但不包括有参的,不能增强,有一个不能输出日志
参数列表:
可以直接写数据类型:
基本数据类型直接写名称 int
引用数据类型写包名,类名的方式 java.lang.String
可以写*,表示所有有参数的方法;
可以写..表示所有有参和无参的方法
全通配写法:
* *..*.*(..)
实际开发中切入点表达式的通常写法:
切dao业务层实现类下的所有方法
* com.lzh.service.impl.*.*(..)
reborn_0530
原创文章 5获赞 10访问量 236
关注
私信
展开阅读全文