Spring之AOP
1. 自定义一个注解
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AdminOnly { }
2. 被代理类
@Service public class TrainService { @AdminOnly public void move(){ System.out.println("train move"); } }
3. 定义一个切面,包含pointcut和advise
@Aspect @Component public class SecurityAspect { @Pointcut ("@annotation(AdminOnly)") public void adminOnly(){ } @Before("adminOnly()") public void check(){ System.out.println("测试自定义注解、aop"); } }
4. Test
import com.djtu.vwater.VwaterApplication; import com.djtu.vwater.cglib.TrainService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration(classes = VwaterApplication.class) public class VwaterApplicationTest { @Autowired TrainService trainService; @Test public void trainMoveTest(){ trainService.move(); } }
//测试结果
测试自定义注解、aop
train move
在web开发中,都是分层开发,如controller、service、dao层,而这写被注解标注的类的生命周期都是托管给spring容器的,比如controller调用service层的服务,其实不是直接调用service实现类的接口,而是调用spring生成该service的代理类(如果是cglib代理,也就是service的子类;如果是jdk代理,则spring会动态生成一个代理),该代理类调用service时,spring会做一些额外的操作,这也就解释了,在debug模式下,在controller层调用service时,总会进入CglibAopProxy内部类DynamicAdvisedInterceptor的intercept函数中,DynamicAdvisedInterceptor实现了MethodInterceptor接口