1.在创建的spring项目的pom.xml文件中导入相关依赖
< dependencies>
< ! -- spring context依赖-- >
< ! -- 当你引入Spring Context 依赖之后,表示将Spring 的基础依赖引入了-- >
< dependency>
< groupId> org. springframework< / groupId>
< artifactId> spring- context< / artifactId>
< version> 6.0 .2 < / version>
< / dependency>
< ! -- junit-- >
< dependency>
< groupId> org. junit. jupiter< / groupId>
< artifactId> junit- jupiter- api< / artifactId>
< version> 5.6 .3 < / version>
< / dependency>
< ! -- spring aop依赖-- >
< dependency>
< groupId> org. springframework< / groupId>
< artifactId> spring- aop< / artifactId>
< version> 6.0 .2 < / version>
< / dependency>
< ! -- spring aspects依赖-- >
< dependency>
< groupId> org. springframework< / groupId>
< artifactId> spring- aspects< / artifactId>
< version> 6.0 .2 < / version>
< / dependency>
< / dependencies>
2.创建要被代理的目标资源
接口
package com. example. test02 ;
public interface Calculator {
int add ( int i, int j) ;
int sub ( int i, int j) ;
int mul ( int i, int j) ;
int div ( int i, int j) ;
}
实现类
package com. example. test02 ;
import org. springframework. stereotype. Component ;
public class CalculatorImpl implements Calculator {
@Override
public int add ( int i, int j) {
int result = i + j;
System . out. println ( "方法内部 result = " + result) ;
return result;
}
@Override
public int sub ( int i, int j) {
int result = i - j;
System . out. println ( "方法内部 result = " + result) ;
return result;
}
@Override
public int mul ( int i, int j) {
int result = i * j;
System . out. println ( "方法内部 result = " + result) ;
return result;
}
@Override
public int div ( int i, int j) {
int result = i / j;
System . out. println ( "方法内部 result = " + result) ;
return result;
}
}
3.创建bean.xml资源文件,并添加约束、开启组件扫描、开启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= "http: / / www. springframework. org/ schema/ aop
http: / / www. springframework. org/ schema/ aop/ spring- aop. xsd
http: / / www. springframework. org/ schema/ context
http: / / www. springframework. org/ schema/ context/ spring- context. xsd
http: / / www. springframework. org/ schema/ beans
http: / / www. springframework. org/ schema/ beans/ spring- beans. xsd">
< ! -- 开启组件扫描-- >
< context: component- scan base- package = "com.example.annotationAop" > < / context: component- scan>
< ! -- 开启aspectj自动代理,为目标对象生成代理-- >
< aop: aspectj- autoproxy> < / aop: aspectj- autoproxy>
< / beans>
4.创建LogAspect并添加
1)添加@Aspect注解
2)添加@Component 注解
3)创建方法并添加通知类型的注解
package com. example. annotationAop ;
import org. aspectj. lang. ProceedingJoinPoint ;
import org. aspectj. lang. annotation. After ;
import org. aspectj. lang. annotation. Around ;
import org. aspectj. lang. annotation. Aspect ;
import org. aspectj. lang. annotation. Pointcut ;
import org. springframework. stereotype. Component ;
@Aspect
@Component
public class LogAspect {
@After ( value = "execution(public int com.example.annotationAop.CalculatorImpl.*(..))" )
public void afterMethod ( ) {
System . out. println ( "后置通知!!!" ) ;
}
@Around ( value = "method()" )
public Object aroundMethod ( ProceedingJoinPoint joinPoint) {
Object result = null ;
try {
System . out. println ( "环绕通知:目标方法之前执行" ) ;
result = joinPoint. proceed ( ) ;
System . out. println ( "环绕通知:目标方法之后执行" ) ;
} catch ( Throwable e) {
throw new RuntimeException ( e) ;
}
return result;
}
@Pointcut ( value = "execution(public int com.example.annotationAop.CalculatorImpl.*(..))" )
public void method ( ) {
}
}
5.测试
代码
package com. example. annotationAop ;
import org. springframework. context. support. ClassPathXmlApplicationContext ;
public class TestAop {
public static void main ( String [ ] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ( "bean.xml" ) ;
Calculator calculator = context. getBean ( "calculatorImpl" , Calculator . class ) ;
calculator. add ( 1 , 2 ) ;
}
}
结果
6.通知类型
前置通知:使用@Before注解标识,在被代理的目标方法前 执行 返回通知:使用@AfterReturning注解标识,在被代理的目标方法成功结束 后执行(寿终正寝 ) 异常通知:使用@AfterThrowing注解标识,在被代理的目标方法异常结束 后执行(死于非命 ) 后置通知:使用@After注解标识,在被代理的目标方法最终结束 后执行(盖棺定论 ) 环绕通知:使用@Around注解标识,使用try…catch…finally结构围绕整个 被代理的目标方法,包括上面四种通知对应的所有位置