Spring AOP 纯注解实现

导入依赖包
spring-aop,spring-context,spring-aspects,spring-test,junit

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

编写配置类和切面类(这里我放一起)

@Aspect//注册切面
@Configuration//注册配置类
@EnableAspectJAutoProxy//开启AOP
@ComponentScan("com.xiehetao")//注册扫描包
public class SpringAop {
     

    @Pointcut("execution(* com.xiehetao.*.*(..))")
    public void pj(){
     }

    @Before("pj()")
    public void sayHi(){
     
        System.out.println("2");
    }

    @After("pj()")
    public void sayHello(){
     
        System.out.println("5");
    }
    @AfterReturning("pj()")
    public void sayGood(){
     
        System.out.println("6");
    }
    @AfterThrowing("pj()")
    public void sayNo(){
     
        System.out.println("6");
    }

    @Around("pj()")
    //这里需要注意,返回的参数类型要与被加强方法的参数一致,否则会报错
    public int process(ProceedingJoinPoint joinPoint){
     
        System.out.println("1");
        int obj=0;
        try{
     
            obj  = (Integer)joinPoint.proceed();
            System.out.println("4");
        }catch (Throwable e){
     
            return 7;
        }
        return obj;
    }
}

被加强类

@Component
public class Girl /*implement Student*/{
     //实现了接口,java会用JDK动态代理,可以设置成cglib的方式来处理
    public int dance(){
     
        System.out.println("3");
        int i=1/0;//这里注释掉就是正常返回
        return 7;
    }
}

interface Student {
     
    int dance();
}

测试类

@RunWith(SpringJUnit4ClassRunner.class)//junit整合spring
@ContextConfiguration(classes={
     SpringAop.class})//标出配置类,如果是配置文件,使用locations参数
public class test {
     

    @Autowired
    private Girl girl;
    //private Student girl;//如果是jdk动态代理,这里必须是接口类型,如果用上面的注入方式,会报错

    @Test
    public void Test(){
     
        System.out.println(girl.dance());
//        System.out.println(ans);
    }
}

总结:
纯注解方式开发AOP步骤:
1.添加依赖包
spring-aop,spring-context,spring-aspects,spring-test,junit(后俩用于单元测试)
2.标记注解类(相当于xml文件),添加扫描包路径,添加切面,添加AOP动态代理(有两种代理方式,一种是JDK动态代理,通过实现接口的方式,一种是CGlib,通过类的方式来实现,但这种不能增强final类)
3.编写advice(通知)
通知有五种,前置,后置,返回后置,异常通知,环绕通知
通知的执行顺序已经在类中用数字标出来了
优先环绕通知,然后后置通知在返回后置和异常通知之前
建议使用环绕通知
4.关于JDK动态代理和cglib动态代理,测试了下
如果希望用JDK动态代理的方式实现,就定义一个接口,然后实现该接口,在测试时,注入的对象必须是接口类型(实现类的方式注入,会报错,@Autowired查找是按类型查找的,girl有两个类型,一个是接口类型,一个是实体类型)
报错类型:
Error creating bean with name ‘com.xiehetao.test’: Unsatisfied dependency expressed through field ‘girl’;
nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named ‘girl’ is expected to be of type ‘com.xiehetao.Girl’ but was actually of type 'com.sun.proxy.$Proxy29’

如果希望用cglib动态代理的方式实现,直接实现类就可以
这里java是自动判断的,看那种方式合适,默认方式是JDK动态代理

你可能感兴趣的:(java,aop)