[Java] 纯文本查看 复制代码
Spring
AOP
AOP: 面向切面编程, 预编译和动态代理实现
OOP: 面向对象编程
OOD: 面向对象设计
AOP:
静态AOP
动态AOP(Spring的aop)
实现技术:
1.JDK提供的动态代理技术
运行时,在JVM内部动态生成class字节码对象(class对象)
JDK动态代理只针对接口操作!!
newProxyInstance(CladdLoder cl,Class[] interfaces,InvocationHandler h)
第一个参数: 目标类的类加载器对象
第二个参数: 目标类的实现接口的Class[]
第三个参数: InvocationHandler是一接口, 他的作用是代理实例的调用处理程序 实现的接 口, 接口中定义了invoke(Object proxy,Method method,Object[] args)
2.CGLIB(动态字节码增强技术)
注意:cglib它可以为没有实现接口的类做代理,也可以为接口类做代理.
AOP应用场景
AOP应用场景:
日志记录
性能统计
事务处理
安全控制
异常检测
概念
目标对象 targeet 要被增强的对象, 增强该对象的方法
切点 pointcut 要被增强的方法
增强 advise 具体对方法做哪些增强
切面 aspect 切点+通知(增强)
代理对象 proxy 被增强后的对象, 执行具体方法的时候是执行该对象的方法
增强方式
增强方式(实现接口)
前置
后置
环绕
异常
引介
NoclassfoundDef 缺jar包提示
传统springaop开发
步骤:
1.编写目标对象target
2.编写通知advice , 通知需要实现指定接口
3.在配置文件中配置切面(切面=切点+通知)
导入俩jar包
<bean name> target
<bean name="xAdvice" class="通知的全类名"> 通知 具体增强(实现接口!!!)
<aop:config>
<aop:point-cut expression="execution(*包名.接口名/类名.*(..))" id="xPoint"> *代表接口中的所有方法
<aop:advisor advice-ref="xAdvice" pointcut-ref=""/>
AspectJ框架它定义的通知类型有6种
1. 前置通知Before 相当于BeforeAdvice
2. 后置通知AfterReturning 相当于AfterReturningAdvice
3. 环绕通知 Around 相当于MethodInterceptor
4. 抛出通知AfterThrowing 相当于ThrowAdvice
5. 引介通知DeclareParents 相当于IntroductionInterceptor
6. 最终通知After 不管是否异常,该通知都会执行
Spring整合aspectj框架实现的aop
基于xml配置方案
1.创建目标(target)
2.创建通知(增强 advice)
3.在spring的xml配置文件中来配置
关于通知上的参数
关于代理方式选择
基于annotation方案
1.编写目标
2.编写增强(advice)
3.测试
<bean id="orderService" class="cn.itheima.aop.OrderServiceImpl"></bean>
<bean id="orderServiceAdvice" class="cn.itheima.aop.OrderHelper"></bean>
<aop:config>
<aop:aspect ref="orderServiceAdvice">
<aop:pointcut id="xPoint" expression="execution(*cn.itheima.test.IOrderService.*(..))" />
<aop:before method="orderServiceAdvice的方法" pointcut-ref="xPoint"/>
</aop:aspect>
</aop:config>
注解:
在配置文件applicationContext.xml中配置bean扫描和开启aspectj注解自动代理
<?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"
xsi:schemaLocation="
[url=http://www.springframework.org/schema/beans]http://www.springframework.org/schema/beans[/url]
[url=http://www.springframework.org/schema/beans/spring-beans.xsd]http://www.springframework.org/schema/beans/spring-beans.xsd[/url]
[url=http://www.springframework.org/schema/context]http://www.springframework.org/schema/context[/url] [url=http://www.springframework.org/schema/context/spring-context.xsd]http://www.springframework.org/schema/context/spring-context.xsd[/url]
[url=http://www.springframework.org/schema/aop]http://www.springframework.org/schema/aop[/url] [url=http://www.springframework.org/schema/aop/spring-aop.xsd]http://www.springframework.org/schema/aop/spring-aop.xsd[/url]">
<!-- bean扫描 -->
<context:component-scan base-package="com.b3a4a" />
<!--
开启aspectj注解自动代理
proxy-target-class="true" 代表使用cglib动态代理
-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
问题
spring采用的是哪一种动态机制?
如果目标对象,有接口,优先使用jdk动态代理
如果目标对象,无接口,使用cglib动态代理。