Spring AOP @args,@annotation和bean使用示例
@args:使用“@args(注解列表)”匹配当前执行的方法传入的参数持有指定注解的执行
注解类型也必须是全限定类型名
模式 | 描述 |
---|---|
@args(com.learn.annotation.Secure) |
任何一个只接受一个参数的方法,且方法运行时传入的参数持有注解com.learn.annotation.Secure ;动态切入点,类似于arg指示符 |
@annotation:使用“@annotation(注解类型)”匹配当前执行方法持有指定注解的方法
注解类型也必须是全限定类型名
模式 | 描述 |
---|---|
@annotation(com.learn.annotation.Secure) |
当前执行方法上持有注解com.learn.annotation.Secure 将被匹配 |
bean:使用“bean(Bean id或名字通配符)”匹配特定名称的Bean对象的执行方法
Spring ASP扩展的,在AspectJ中无相应概念
模式 | 描述 |
---|---|
bean(*Service) |
匹配所有以Service命名(id或name)结尾的Bean |
示例
@args示例
-
创建注解
- 创建package命名为
com.learn.annotation
(根据实际情况修改) - 创建注解
Secure
,内容如下@Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Secure { }
- 创建package命名为
-
创建实体类
创建package命名为
com.learn.model
(根据实际情况修改)-
创建类
User
,内容如下public class User { public String getName() { return "user"; } }
-
创建
Member
继承User
,并加上注解@Secure
,内容如下@Secure public class Member extends User{ @Override public String getName() { return "member"; } }
-
创建
Leader
继承Member
,内容如下public class Leader extends Member{ @Override public String getName() { return "leader"; } }
-
创建服务
创建package命名为
com.learn.service
(根据实际情况修改)-
创建接口
IHelloService
,内容如下public interface IHelloService { void sayHello(User user); void secureSay(); }
创建package命名为
com.learn.service.impl
(根据实际情况修改)-
创建接口
IHelloService
的实现类HelloServiceImpl
,内容如下@Service public class HelloServiceImpl implements IHelloService { @Override public void sayHello(User user) { System.out.println(user.getName() + ":hello"); } }
-
创建AOP
- 创建package命名为
com.learn.aop
(根据实际情况修改) - 配置AOP,新建
ExecutionAOP
,内容如下@Aspect @Component public class ExecutionAop { @Before("execution(* com.learn..*(..)) && @args(com.learn.annotation.Secure)") public void execute1(){ System.out.println("@args(com.learn.annotation.Secure)"); } }
- 创建package命名为
-
创建测试用例
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Resource private IHelloService helloService; @Test public void test1() { System.out.println("------------------User-----------------"); helloService.sayHello(new User()); System.out.println("------------------Member-----------------"); helloService.sayHello(new Member()); System.out.println("------------------Leader-----------------"); helloService.sayHello(new Leader()); } }
运行测试用例可得到结果
------------------User----------------- user:hello ------------------Member----------------- @args(com.learn.annotation.Secure) member:hello ------------------Leader----------------- leader:hello
由此可知,@args会根据传入的参数取动态的匹配方法。
@annotation示例
-
添加方法
-
在接口
IHelloService
中新增方法,内容如下public interface IHelloService { void secureSay(); }
-
在其实现类中实现该方法
@Service public class HelloServiceImpl implements IHelloService { @Secure @Override public void secureSay() { System.out.println("hello"); } }
-
-
新增AOP监听
- 在
ExecutionAOP
中新增监听,内容如下@Aspect @Component public class ExecutionAop { @Before("@annotation(com.learn.annotation.Secure)") public void execute2(){ System.out.println("@annotation(com.learn.annotation.Secure)"); } }
- 在
-
创建测试用例
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Resource private IHelloService helloService; @Test public void test2() { helloService.secureSay(); } }
运行测试用例可得到结果
@annotation(com.learn.annotation.Secure) hello
可以看出加了注解的方法确实被AOP匹配到了。
@bean示例
-
创建服务
-
在
com.learn.service
包中创建接口IExceptService
public interface IExceptService { void sayHello(); }
-
在
com.learn.service.impl
包中创建其实现类ExceptService
@Service public class ExceptService implements IExceptService { @Override public void sayHello() { System.out.println("hello"); } }
-
-
新增AOP监听
- 在
ExecutionAOP
中新增监听,内容如下@Aspect @Component public class ExecutionAop { @Before("bean(*Service)") public void execute3(){ System.out.println("bean(*Service)"); } }
- 在
-
创建测试用例
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Resource private IExceptService exceptService; @Test public void test3() { exceptService.sayHello(); } }
运行测试用例可得到结果
bean(*Service) hello
可以看出命名以Service结尾的服务中的方法确实被AOP匹配到了。