连接点:已经拦截
切入点:要拦截的方法。通过配置声明
通知(增强):方法的增强,增强的逻辑操作
织入:
切面:
Spring AOP的底层实现
Jdk的动态代理:proxy和target是兄弟关系,实现同一个接口
Cglib动态代理:proxy和target是父子关系。(不需要实现接口)
创建一个Enhancer
指定父
指定回调函数
生成代理对象
传统的AOP和aspect的区别:
AspectJ
1.简述你是怎样理解AOP思想
AOP:1>面向切面编程。AOP的底层就是动态代理机制。
2>将我们和业务关系不大的逻辑横向抽取出来(例如事务处理,日志,性能控制),利用AOP实现分离解耦。实现类的维护性
3>Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
横向的切面技术解决纵向的逻辑问题,优点:解决耦合度的问题
2.Spring中aop开发底层实现是通知什么实现的?
动态代理:JDK动态代理
CGLIB动态代理
3.Spring中传统的aop开发,它有通知类型有哪些?
前置:实现MethodBeforAdvice接口
后置:实现AfterReturningAdvice接口
环绕:实现MethodIntercepter接口
异常抛出:实现ThrowsAdvice接口
引介通知:实现IntroductionAdvice接口
4.Spring中aspectj框架的通知类型有哪些
前置:
后置:
环绕:
抛出异常通知:
最终通知:
引介通知
1>首先定义一个目标类:
public class UserDao(){
public void add(){
syso("add..")
}
}
2>定义一个切面的类,目的是为了让目标里的方法增强
public class UserDaoAspect(){
//前置增强
public void before(){
syso("日志的记录");
}
}
3>然后在xml里面进行配置
a>定义目标的类
b>定义切面的类
c>定义切面
//声明切点
//声明通知
=======此种方法应用在注解上=================
1>使用注解定义一个目标类。
@Service("userService")
public class UserService {
public void add(){
System.out.println("添加");
}
2>使用注解生成一个切面;注意:这个切面的类也得使用注解生成Bean
@Component("userServiceAspect ")
@Aspect
public class UserServiceAspect {
使用@aspect声明这个类是切面
使用@Component声明这个类Bean对象
3>在切面类 UserServiceAspect这个类中的方法上使用
@Before
@AfterReturning
@Around
@AfterThrowing
@After
来声明通知,在这些注解中可以使用参数value来定义切点
例如 @Before(value=“execution(* cn.itcast..*.*(..))”)
对于@AfterReturing 它还有一个returning属性用于描述接收返回值
对于@AfterThrowing它还有一个参数 throwing来接收返回的异常对象
4>在applectionContext.xml中
开启扫描bean的注解
开启扫描aspectj框架的注解
@PointCut注解定义切入点
要使用这个注解,要求在切面类中声明一个无参数,非静态的方法
你定义的这个方法的名称就相当于是切点名称
这种用法解决的问题:
可以为多个通知定义同一个切入点,不用在每一个通知上添加切入点。
注解的环绕通知
注解的异常抛出
基于xml的环绕通知
//创建一个切面的类 这个通知是环绕通知,在方法执行前后都会对目标方法进行增强
public class UserDaoAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
long l=System.currentTimeMillis();
System. out.println(l);
//调用目标中的方法
Object result = mi.proceed();
System. out.println("执行了:" +(System.currentTimeMillis ()-l)+"毫秒" );
return result;
}
}