spring框架AOP
cglib代理:
由于静态代理需要实现目标对象的相同接口,那么可能会导致代理类会不好维护,因此出现了动态代理。
动态代理的目标对象一定是要有接口的,没有接口就不能实现动态代理,因此出现了cglib代理。
cglib代理也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能。
cglib是一个强大的高性能的代码生成包,他可以在运行期扩展java类与实现java接口。他广泛的被许多AOP框架使用,为他们提供丰富的interaction拦截。
AOP编程思想:
AOP:(aspect object programming)面向切面编程
AOP是面向切面的编程思想:将业务逻辑模块中,需要进行处理的功能点,从逻辑的角度将其作为这个整体,就可以看做是这些不同模块中的逻辑点构成的一个面,这个面就是切面。
功能:让关注点代码与业务代码分离。面向切面编程是指:对很多功能都有的重复代码抽取,再运行的时候往业务方法上动态织入“切面类代码”。
AOP编程内容要求:
连接点(JoinPoint):进行切面业务处理时的时机点,例如方法执行前、方法执行后、抛出异常等时机点。
增强(Advice):添加特定连接点上的一段业务逻辑处理代码,也就是在链接点上执行的业务处理过程,就是在特定链接点上触发的一组动作。
切入点(PointCut):被增强的链接点就是切入点,添加了增强功能的连接点。(
切面(Aspect):切面有切入点和增强构成。切面就是切入点的集合。AOP就是通过切面来管理连接点和增强的。关注点形成的类就叫做切面。
织入(Weaving):将增强添加到目标对象的具体的链接点的过程,也就是将增强和连接点结合的过程就是织入。
目标对象(Target):需要添加增强的目标类(被代理的目标类)。
引入(Introduction):是一种特殊的增强,可以为目标对象添加一些属性和方法,一般用作动态的给目标对象附加一些行为能力。
代理(Proxy):目标对象通过AOP生成的代理代理和目标对象之间是代理和被代理的关系
总结:
把“增强”使用“织入”的方式结合在“连接点”上,就构成了“切入点”。“切入点”汇集成“切面”。AOP就是使用动态代理等方式对切面的管理机制。
使用spring AOP 开发步骤:
引入aop相关的jar文件。可以搜索maven repository
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.4</version>
</dependency>
bean.xml文件中引入aop名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
XML方式实现AOP编程
<!--配置Advice增强业务逻辑处理类的bean对象-->
<bean class="com.Liuxu.Advice.MyLoginAdvice" id="myLoginAdvice"></bean>
<!--AOP的配置-->
<!--切入点的配置,主要配置选择那些连接点作为切入点增强。
重点配置:连接点的选取规则,使用类正则表达式进行选择
id:唯一性名字命名
expression:使用类正则表达式配置连接点的选取规则
切入点的类正则表达式的说明:* com.Liuxu..*.do*(..)
第一个*表示:方法的返回值类型为任意类型;
com.Liuxu..* 表示:com.Liuxu开头的所有包下的所有的类,末尾的*表示类名
do*(..) 表示:其中 do* 表示以do开头的方法名,(..)表示方法的参数列表为任意参数
-->
<!--切面配置:主要是将pointcut切入点和增强进行织入结合的配置-->
<!--Aspect配置节点中的ref用于指定该切面使用的增强(业务逻辑处理类)-->
<!--如果使用advise进行配置,则要求advise引用的‘增强’业务逻辑类,必须实现了spring的增强接口-->
<aop:config>
<!--除了使用pointcut筛选连接点,可以使用advisor进行定义,但是advisor要求引入的
‘增强’业务逻辑处理类,必须实现spring提供的spring专业的增强类-->
<aop:pointcut id="loggingPointcut" expression="execution(* com.Liuxu..*.do*(..))"/>
<aop:aspect ref="myLoginAdvice" id="myAspect">
<!--切面的前置增强的织入配置-->
<aop:before method="doBeforeLogging" pointcut-ref="loggingPointcut"></aop:before>
<!--切面的后置增加的织入配置-->
<aop:after method="doAfterLogging" pointcut-ref="loggingPointcut"></aop:after>
</aop:aspect>
</aop:config>
@Test
public void test02() {
//从spring容器中获取指定name或者id的java实体类对象
Student student01 = context.getBean("student01",Student.class);
//调用行为
student01.doStuding();
student01.doGaming();
Teacher teacher = context.getBean("teacher01",Teacher.class);
teacher.doTeacher();
}
切入点表达式:execution()
? :代表0或1,可以不写
* :代表任意类型,0或者更多
.. :参数为 .. 表示为可变参数