标签:功能 认识 Spring 代码 切点 切面 Aspect AOP public
一.AOP简介
Aop------面向切面编程(Aspect Oriented Programing)在传统的编程实践中,对于系统中有些行为,我们无法分装在单个的模块中,而且这些功能与行为通常并不实现系统的业务功能,但辅助系统业务功能的实现,并散布在实现系统业务功能的多个模块中.如果采用传统的OOP编程,通常会造成这些功能的代码纠缠于实际的业务代码,造成代码纠结,同时带来了代码的侵入性.
为此,我们希望能够将这些无法分装在单个模块中的功能与行为,集中于一个横切面(Cross-cutting)上,然后在这个横切面上进行代码的编写,编写完成之后通过织入(Weaving)机制,将这个横切面织入到系统的业务功能模块中,使得业务功能的实现都需要通过改横切面,从而实现在实际的业务功能之前或者之后也同时实现了该横切面所提供的功能和行为.
程序运行流程如下:
二.Aop常用概念
2.1 Advice(增强/通知)
所需要的横切面的功能m,比如日志,事务处理等
2.2 PointCut(切点)
程序运行中的某个阶段点,如某个方法调用全,后,异常抛出等.在这个阶段点处,
Advice所定义的功能和行为被织入到实际的业务功能中.
2.3 JoinPoint(连接点)
指具体的某个类的某个方法的切点位置.比UserInfo类的getUserName()方法执行前,后等
2.4 Introduction(引阶))
是一种比较特殊的增强类型,它不是目标方法周围织入增强,而是为目标创建新的方法和属性.
所以引阶增强的连接点是类级别的.
2.5 target(目标对象)
只将被加入横切代码Advice的执行对象
2.6 织入(Weaving)
将Advice加入到目标对象的指定连接点的过程.
织入分为3种类型:
编译期织入:指在代码编写时织入的代码;
类加载期织入:指在类加载器加载时织入;
运行期织入:在程序运行时动态加入的代码(动态代理)
2.7 代理(Proxy)
(1).JDK动态代理
Jdk1.3以后,java提供了动态代理技术,允许开发者在运行期创建接口的代理实例
(2)Cglib动态代理
在运行时动态生成一个子类对象,在子类对象中拦截父类所有方法的调用
2.8 切面(Aspect)
切面包含横切代码和连接点信息,所以一个切点无法构成一个切面,必须有切点+增强,或者是一个增强构成一个切面.
把一个功能增强织入到一个切点上就形成了切面
三.Spring-AOP示例 配置文件写法:
3.1 构建不带模板的maven-java工程
发现复写方法时报红,这是因为jdk编译版本过低(jdk1.5),在pom.xml中添加jdk插件<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
3.2 配置文件
spring-config.xml3.3 测试类
运行结果:
配置文件有两种写法:
(1)
<bean id="myAdvice1" class="com.whx.service.advices.MyAdvice1"></bean>
<bean id="myAdvice2" class="com.whx.service.advices.MyAdvice2"></bean>
<bean id="myAdvice3" class="com.whx.service.advices.MyAdvice3"></bean>
<!--aop核心配置-->
<aop:config>
<!--指明切点位置-->
<aop:pointcut id="myPointCut1" expression="bean(userServiceImpl)"></aop:pointcut>
<aop:pointcut id="myPointCut2" expression="bean(orderServiceImpl)"></aop:pointcut>
<!--将增强织入切点形成切面-->
<aop:advisor advice-ref="myAdvice1" pointcut-ref="myPointCut1"></aop:advisor>
<aop:advisor advice-ref="myAdvice2" pointcut-ref="myPointCut1"></aop:advisor>
<aop:advisor advice-ref="myAdvice3" pointcut-ref="myPointCut1"></aop:advisor>
</aop:config>
(2)
<bean id="beforeAdvice" class="com.whx.service.advice2.BeforeAdvice"></bean>
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="beforeAdvice">
<aop:before method="dosomethingBefore" pointcut-ref="myPC1"></aop:before>
</aop:aspect>
</aop:config>
四.AOP的五种功能增强
按照位置划分:4.1 前置切面:before
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="beforeAdvice">
<aop:before method="dosomethingBefore" pointcut-ref="myPC1"></aop:before>
</aop:aspect>
</aop:config>
4.2 后置切面:after
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="afterAdvice">
<aop:after method="doSomethingAfter" pointcut-ref="myPC1"></aop:after>
</aop:aspect>
</aop:config>
4.3 报错时执行:after-throwing
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="exceptionAdvice">
<aop:after-throwing method="onError" pointcut-ref="myPC1"></aop:after-throwing>
</aop:aspect>
</aop:config>
4.4 不报错执行:after-returning
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="noException">
<aop:after-returning method="notError" pointcut-ref="myPC1"></aop:after-returning>
</aop:aspect>
</aop:config>
4.5 环绕切面:around
<!--aop核心配置-->
<aop:config>
<aop:pointcut id="myPC1" expression="bean(userServiceImpl)"/>
<aop:aspect ref="aroundAdvice">
<aop:around method="beforeAndAfter" pointcut-ref="myPC1"></aop:around>
</aop:aspect>
</aop:config>
五.基于注解操作AOP
配置文件添加AOP对于注解的支持:<!--AOP对于注解的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
描述切点位置@Pointcut
@Component
public class MyPointCut {
@Pointcut("bean(userServiceImpl)")
public void pc1(){
}
}
5.1 前置切点:
@Aspect @Before@Component
@Aspect
public class BeforeAdvice {
@Before("com.whx.service.advice2.MyPointCut.pc1()")
public void dosomethingBefore(){
System.out.println("BeforeAdvice.dosomethingBefore");
}
}
5.2 后置切点:
@Aspect @After@Component
@Aspect
public class AfterAdvice {
@After("com.whx.service.advice2.MyPointCut.pc1()")
public void doSomethingAfter(){
System.out.println("AfterAdvice.doSomethingAfter");
}
}
5.3 不报错切点::
@Apsect @AfterReturning@Component
@Aspect
public class NoException {
@AfterReturning("com.whx.service.advice2.MyPointCut.pc1()")
public void notError(){
System.out.println("NoException.notError");
}
}
5.4 报错执行切点:::
@Apsect @AfterThrowing@Component
@Aspect
public class ExceptionAdvice {
@AfterThrowing("com.whx.service.advice2.MyPointCut.pc1()")
public void one rror(){
System.out.println("ExceptionAdvice.onError");
}
}
5.5 环绕切点:::
@Apsect @Around@Component
@Aspect
public class AroundAdvice {
@Around("com.whx.service.advice2.MyPointCut.pc1()")
public void beforeAndAfter(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("AroundAdvice.before.");
//调用执行原始功能
proceedingJoinPoint.proceed();
System.out.println("AroundAdvice.after");
}
}
风里雨里,我在善知教育等你!!
需要加Q:1763481971
标签:功能,认识,Spring,代码,切点,切面,Aspect,AOP,public 来源: https://blog.csdn.net/weixin_43555093/article/details/100062094
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。