了解了如何使用注解注册Bean之后,我们接着来看如何通过注解实现AOP操作,首先我们需要在主类添加@EnableAspectJAutoProxy
注解,开启AOP注解支持:
- @EnableAspectJAutoProxy
- @ComponentScan("com.test.bean")
- @Configuration
- public class MainConfiguration {
- }
接着我们只需在定义AOP增强操作的类上添加@Aspect
注解和@Component
将其注册为Bean即可,就像我们之前在配置文件中也要将其注册为Bean:
- @Component
- @Aspect
- public class AopTest {
-
- }
接着,我们直接在里面编写方法,并将此方法添加到一个切点中,比如我们希望在Student的test方法执行之前执行我们的方法:
- public int test(String str){
- System.out.println("我被调用了:"+str);
- return str.length();
- }
只需要添加@Before
注解即可:
- @Before("execution(* com.test.bean.Student.test(..))")
- public void before(){
- System.out.println("我是之前执行的内容!");
- }
同样的,我们可以为其添加JoinPoint
参数来获取切入点信息:
- @Before("execution(* com.test.bean.Student.test(..))")
- public void before(JoinPoint point){
- System.out.println("参数列表:"+ Arrays.toString(point.getArgs()));
- System.out.println("我是之前执行的内容!");
- }
我们也可以使用@AfterReturning
注解来指定方法返回后的操作:
- @AfterReturning(value = "execution(* com.test.bean.Student.test(..))", returning = "returnVal")
- public void after(Object returnVal){
- System.out.println("方法已返回,结果为:"+returnVal);
- }
我们还可以指定returning属性,并将其作为方法某个参数的实参。同样的,环绕也可以直接通过注解声明:
- @Around("execution(* com.test.bean.Student.test(..))")
- public Object around(ProceedingJoinPoint point) throws Throwable {
- System.out.println("方法执行之前!");
- Object val = point.proceed();
- System.out.println("方法执行之后!");
- return val;
- }
配置文件可能不止一个,我们有可能会根据模块划分,定义多个配置文件,这个时候,可能会出现很多个配置类,如果我们需要@Import
注解来快速将某个类加入到容器中,比如我们现在创建一个新的配置文件,并将数据库Bean也搬过去:
- public class Test2Configuration {
- @Bean
- public Connection getConnection() throws SQLException {
- System.out.println("创建新的连接!");
- return DriverManager.getConnection("jdbc:mysql://localhost:3306/study",
- "root",
- "root");
- }
- }
- @EnableAspectJAutoProxy
- @Configuration
- @ComponentScan("com.test")
- @Import(Test2Configuration.class)
- public class TestConfiguration {
-
- @Resource
- Connection connection;
-
- @PostConstruct
- public void init(){
- System.out.println(connection);
- }
- }
注意另一个配置类并没有添加任何注解,实际上,相当于导入的类被强制注册为了一个Bean,到现在,我们一共了解了三种注册为Bean的方式,利用这种特性,我们还可以将其他的类型也强制注册为Bean:
- @EnableAspectJAutoProxy
- @Configuration
- @ComponentScan("com.test")
- @Import({Test2Configuration.class, Date.class})
- public class TestConfiguration {
-
- @Resource
- Connection connection;
- @Resource
- Date date;
-
- @PostConstruct
- public void init(){
- System.out.println(date+" -> "+connection);
- }
- }
可以看到,日期直接作为一个Bean放入到IoC容器中了,并且时间永远都是被new的那个时间,也就是同一个对象(因为默认是单例模式)。
通过@Import
方式最主要为了实现的目标并不是创建Bean,而是为了方便一些框架的Registrar
进行Bean定义,在讲解到Spring原理时,我们再来详细讨论,目前只做了解即可。