已经快一个月没有更新博客了,这一个月的事情有点多,并且我部署到github上的博客被墙了,现在重新部署到了云服务器上。接下来就继续Spring框架的总结。
aop 为Aspect Oriented Programming的缩写,意为面向切面编程。意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。aop编程的优点在于,不更改源码的情况下,aop可以进行权限的验证,日志记录,性能检测,事务控制。
<?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: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">
</beans>
配置切面类
<!-- 把要增强的目标交给Spring管理-->
<bean id="userServiceImpl" class="com.spring.service.impl.UserServiceImpl"></bean>
<!--把通知所在的类也交给Spring管理-->
<!-- 配置aop切面 -->
<bean id="myAspectj" class="com.spring.aspectj.MyAspectj"></bean>
<aop:config>
<!-- 切入点: 指定要被增强哪个类里面哪个方法;*:表示任何的修饰符或返回值类型 ; ..表示匹配add()方法中里面可以有任意参数 -->
<aop:pointcut expression="execution(* com.spring.service.UserService.add(..))" id="p1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectj">
<!-- 把check通知的织入切入点p1(目标类的方法之前) -->
<aop:before method="check" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>
</beans>
通知的类型
<aop:config>
<!-- 切入点: 指定要被增强哪个类里面哪个方法;*:表示任何的修饰符或返回值类型 ; ..表示匹配add()方法中里面可以有任意参数 -->
<aop:pointcut expression="execution(* com.spring.service.UserService.add(..))" id="p1"/>
<aop:pointcut expression="execution(* com.spring.service.UserService.select(..))" id="p2"/>
<aop:pointcut expression="execution(* com.spring.service.UserService.selectReturn(..))" id="p3"/>
<aop:pointcut expression="execution(* com.spring.service.UserService.update(..))" id="p4"/>
<aop:pointcut expression="execution(* com.spring.service.UserService.delete(..))" id="p5"/>
<aop:pointcut expression="execution(* com.spring.service.UserService.deleteAfter(..))" id="p6"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectj">
<!-- 把check通知的织入切入点p1(目标类的方法之前) -->
<aop:before method="check" pointcut-ref="p1"/>
<aop:after-returning method="back" pointcut-ref="p2"/>
<aop:after-returning method="backReturn" pointcut-ref="p3" returning="obj"/> <!--obj名字取MyAspectj类中的backReturn(Object obj)-->
<aop:around method="around" pointcut-ref="p4"/>
<aop:after-throwing method="doException" pointcut-ref="p5"/>
<aop:after method="doAfter" pointcut-ref="p6"/>
</aop:aspect>
</aop:config>
//这是做增强功能的类
public class MyAspectj {
public void check(){ //通知
System.out.println("--校验身份--");
}
public void back(){
System.out.println("--之后执行--");
}
public void backReturn(Object obj){
System.out.println("--之后执行,返回的数据:"+(String)obj);
}
public void around(ProceedingJoinPoint point) throws Throwable { //point用来接收切入点update()
System.out.println("--之前操作--");
point.proceed(); //执行跌入点
System.out.println("--之后操作--");
}
public void doException(){ //被增强的切入点报异常之后会执行,不报异常不会执行
System.out.println("--异常抛出了--");
}
public void doAfter(){
System.out.println("--不管有没有异常始终都会执行--");
}
}
//使用场景:前置通知:转账之前校验用户名和密码及余额
基于execution的函数完成的语法
execution([访问修饰符] 方法返回值 包名.类名.方法名(参数)),com.spring.service.UserServiceImpl.*(..) 开发中用的最多的是这种,对当前类下所有的方法做增强处理(场景:事务处理)。
Spring注解的通知类型
开启注解的aop开发
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
前置通知:@Before
后置通知:@AfterReturning(value="execution()",returning="result")
环绕通知:@Around
异常抛出通知:@AfterThrowing(value="execution()",throwing="e")
最终通知:@After
增强类
package com.spring.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Value;
/**
* 这是做增强功能的类
*/
@Aspect //注解通知类,告知Spring这是通知所在的类
public class MyAspectj {
@Before(value = "execution(* com.spring.service.UserService.add(..))")
public void check(){ //通知
System.out.println("--校验身份--");
}
@AfterReturning(value = "execution(* com.spring.service.UserService.select(..))")
public void back(){
System.out.println("--之后执行--");
}
@AfterReturning(value = "execution(* com.spring.service.UserService.selectReturn(..))",returning = "obj")
public void backReturn(Object obj){
System.out.println("--之后执行,返回的数据:"+(String)obj);
}
@Around(value = "execution(* com.spring.service.UserService.update(..))")
public void around(ProceedingJoinPoint point) throws Throwable { //point用来接收切入点update()
System.out.println("--之前操作--");
point.proceed(); //执行跌入点
System.out.println("--之后操作--");
}
@AfterThrowing(value = "execution(* com.spring.service.UserService.delete(..))",throwing = "e") //e可以接收切入点抛出的异常
public void doException(Exception e){ //被增强的切入点报异常之后会执行,不报异常不会执行
System.out.println("--异常抛出了--");
System.out.println(e.toString());
}
@After(value = "execution(* com.spring.service.UserService.deleteAfter(..))")
public void doAfter(){
System.out.println("--不管有没有异常始终都会执行--");
}
}
配置文件:
<?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: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"> <!-- bean definitions here -->
<!--开启AOP注解开发-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 把要增强的目标交给Spring管理-->
<bean id="userServiceImpl" class="com.spring.service.impl.UserServiceImpl"></bean>
<!--把通知所在的类也交给Spring管理-->
<!-- 配置aop切面 -->
<bean id="myAspectj" class="com.spring.aspectj.MyAspectj"></bean>
</beans>
第三种方式就是实现Spring中的API,来获得面向切面编程的能力。
首先需要写增强类BeforeLog来实现 MethodBeforeAdvice接口。MethodBeforeAdvice中的抽象方法before,就是xml配置中的前置通知before。如果还需要后置通知after-returning等,也可以采用多实现接口AfterReturningAdvice。
public class BeforeLog implements MethodBeforeAdvice,AfterReturningAdvice{
//method : 要执行的目标对象的方法
//objects : 被调用的方法的参数
//Object : 目标对象
@Override
public void before(Method method, Object[] objects, Object object) throws Throwable {
System.out.println("对象为"+object.getClass().getName()+"方法名称为:"+method.getName());
}
//returnValue 返回值
//method被调用的方法
//args 被调用的方法的对象的参数
//target 被调用的目标对象
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("对象"+target.getClass().getName()+"的,方法名为:"+method.getName()+"返回值:"+returnValue);
}
}
配置文件中需要将增强类或被增强类都注册到spring容器中,然后再配置切入点和切面
<!--注册bean-->
<bean id="userService" class="com.aop.demo01.service.impl.UserServiceImpl"></bean>
<bean id="beforeLog" class="com.aop.demo01.aspect.BeforeLog"/>
<!--配置aop-->
<!--实现Spring 的API-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut" expression="execution(* com.aop.demo01.service.impl.UserServiceImpl.*(..))"/>
<!--执行环绕; advice-ref执行方法 . pointcut-ref切入点-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<!-- <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>-->
</aop:config>
原文:https://www.cnblogs.com/fufengxi/p/14592687.html