前面的文章分析了spring的启动流程,从本文开始,我们来分析spring aop功能。
1. 示例demo
1.1 准备demo
aop的示例demo依旧位于spring-learn
模块,包名是org.springframework.learn.demo02
,目录结构如下:
- 准备 annotation 首先,我们准备一个annotation用来标注切面:
package org.springframework.learn.demo02;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AopAnnotation {
}
复制代码
- 编写切面方法
package org.springframework.learn.demo02;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* {这里添加描述}
*
* @author chengyan
* @date 2020-07-19 6:00 下午
*/
@Aspect
@Component
public class AopAspectj {
@Pointcut("@annotation(org.springframework.learn.demo02.AopAnnotation)")
public void testAop(){
}
@Around("testAop()")
public Object around(ProceedingJoinPoint p){
System.out.println("before execute...");
Object o = null;
try {
o = p.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("after execute...");
return o;
}
}
复制代码
这个类表示,标注了 @AopAnnotation
的方法,将运行其运行前后运行一些代码,around(ProceedingJoinPoint)
指定了运行前后的代码。
- 启用proxy
package org.springframework.learn.demo02;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Component
public class AopAnnotationConfig {
}
复制代码
这个类关键在于上面的两个注解:@EnableAspectJAutoProxy
、@Component
,前者表示启用代理,后者表示该类为spring bean.
- 准备三个类
- 继承了接口且标有注解
AopAnnotation
的类AopBean1
- 未继承接口但标有注解
AopAnnotation
的类AopBean2
- 未继承接口也未标有注解
AopAnnotation
的类AopBean3
这几个类的内容分别如下:
IAopBean.java
package org.springframework.learn.demo02;
public interface IAopBean {
void hello();
}
复制代码
AopBean1.java
package org.springframework.learn.demo02;
import org.springframework.stereotype.Component;
@Component
public class AopBean1 implements IAopBean {
@Override
@AopAnnotation
public void hello() {
System.out.println("实现了接口IAopService的hello()");
}
}
复制代码
AopBean2.java
package org.springframework.learn.demo02;
import org.springframework.stereotype.Component;
@Component
public class AopBean2 {
@AopAnnotation
public void hello() {
System.out.println("未实现接口IAopService的hello()");
}
}
复制代码
AopBean3.java
package org.springframework.learn.demo02;
import org.springframework.stereotype.Component;
@Component
public class AopBean3 {
public void hello() {
System.out.println("未实现接口IAopService、也未进行aop的hello()");
}
}
复制代码
- 启动类
package org.springframework.learn.demo02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Demo02Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
"org.springframework.learn.demo02");
IAopBean obj1 = (IAopBean)context.getBean("aopBean1");
AopBean2 obj2 = (AopBean2)context.getBean("aopBean2");
AopBean3 obj3 = (AopBean3)context.getBean("aopBean3");
System.out.println("obj1:" + obj1.getClass());
obj1.hello();
System.out.println("-----------------------");
System.out.println("obj2:" + obj2.getClass());
obj2.hello();
System.out.println("-----------------------");
System.out.println("obj3:" + obj3.getClass());
obj3.hello();
}
}