1. 概念
面向切面编程:一种编程思想。 proxy动态代理(实现了这种思想):在原方法执行时,给原方法的前面或着后面增加其他的方法。增加的方法并不会写在原方法中 原方法就是目标方法, 增加的方法就是代理方法 面向切面的好处: 不必修改原来的代码 方法中只负责业务的逻辑,像验证、日志、事务管理都可以使用切面解决 面向切面的7个名词: 连接点:指的是位置,也就是原方法的前面和后面 切点:在连接点使用的代理方法 通知:①目标方法之前:前置通知,②目标方法之后:后置通知,③前后都有:环绕通知,④目标方法异常时执行:异常通知,⑤finall里面:最终通知 切面: 织入:描述过程。 目标对象 代理对象
2. 全注解开发
1. 文件结构
依赖
< dependency> < groupId> org.springframework</ groupId> < artifactId> spring-context</ artifactId> < version> 6.1.14</ version> </ dependency> < dependency> < groupId> org.springframework</ groupId> < artifactId> spring-aspects</ artifactId> < version> 6.1.14</ version> </ dependency>
2. 目标对象
import org. springframework. stereotype. Component ;
@Component
public class TargetObject { public void targetMethod ( ) { System . out. println ( "目标对象执行:................" ) ; }
}
3. 切面类
@Component
@Aspect
@Order ( 1 )
public class FirstAopClass { @Pointcut ( "execution(* com.example.service.TargetObject.*(..))" ) public void pointCut ( ) { } @Before ( "pointCut()" ) public void before ( JoinPoint joinPoint) { System . out. println ( "前置通知:1" ) ; String targetClassName = joinPoint. getSignature ( ) . getDeclaringTypeName ( ) ; String targetMethodName = joinPoint. getSignature ( ) . getName ( ) ; Object [ ] args = joinPoint. getArgs ( ) ;
} @AfterReturning ( "pointCut()" ) public void afterReturning ( ) { System . out. println ( "后置通知:1" ) ; } @Around ( "pointCut()" ) public void around ( ProceedingJoinPoint pjp) throws Throwable { System . out. println ( "环绕前置通知:1" ) ; pjp. proceed ( ) ; System . out. println ( "环绕后置通知:1" ) ; } @AfterThrowing ( "pointCut()" ) public void afterThrowing ( ) { System . out. println ( "异常通知:1" ) ; } @After ( "pointCut()" ) public void after ( ) { System . out. println ( "最终通知:1" ) ; }
}
4. 配置类
import org. springframework. context. annotation. ComponentScan ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. context. annotation. EnableAspectJAutoProxy ;
@Configuration
@ComponentScan ( { "com.example.service" } )
@EnableAspectJAutoProxy ( proxyTargetClass = true )
public class SpringConfig { }
5. 测试方法
@Test public void test ( ) { ApplicationContext ctx = new AnnotationConfigApplicationContext ( SpringConfig . class ) ; TargetObject targetObject = ctx. getBean ( "targetObject" , TargetObject . class ) ; targetObject. targetMethod ( ) ; }
6. 执行顺序
环绕前置通知:1
前置通知:1
目标对象执行:. . . . . . . . . . . . . . . .
后置通知:1
最终通知:1
环绕后置通知:1