Spring基础AOP示例

AOP 面向切面 
AOP面向切面 = OOP面向对象编程
Spring的AOP存在的目的是为了解耦,AOP可以让一组一类共享相同的行为,
在OOP中只能通过几次类和实现接口,来实现代码耦合度增强。且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足

Spring支持AspectJ的注解式切面编程
使用@Aspect声明是一个切面
使用@After,@Before,@Around定义建言(advice),可直接将拦截规则(切点)作为参数
其中@After,@Before,@Around参数的拦截规则为切点(PointCut),为了使切点复用。可以使用@pointCut专门拦截规则
然后在@After,@Before,@Around的参数中调用
其中符合条件的每一个被拦截处为连接点JoinPoint
Spring本身在事务处理@Transcational和数据库@Caheable 上,都使用了这种形式的拦截

附代码

配置好maven架包 Spring aop支持及AspectJ依赖

        <!-- Spring aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>

        <!-- Spring aspectj -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>

接口文件 拦截规则的注解

注解本身没有功能,和xml一样。注解和xml都是一种元数据,元数据即解释数据的数据 ,即所谓的配置

注解的功能来自用这个注解的地方


package com.example.demo.aop;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
    String name();
}

使用注解的被拦截类

package com.example.demo.aop;

import org.springframework.stereotype.Service;
 

@Service
public class DemoAnnotationService {

    @Action(name="注解式拦截的add操作")
    public void add(){}

}

使用方法规则被拦截类

package com.example.demo.aop;

import org.springframework.stereotype.Service;
 
@Service
public class DemoMethodService {

    public void add(){}
}

切面类

@Before("execution(* com.example.demo.aop.DemoMethodService.*(..))")  规则描述

execution :表示执行方法的时候会触发

" * " :星号表示任意返回类型的方法
com.example.demo.aop.DemoMethodService.*(..) 被代理的方法,这里也可以不用写实现类的方法,直接写接口方法

(..):任意的参数


package com.example.demo.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
 
@Aspect   // 注解声明一个切面
@Component  // @Conmponent让切面成为一个Spring容器管理的Bean
public class LogAspect {

    @Pointcut("@annotation(com.example.demo.aop.Action)")    //通过Pointcut注解声明切点
    public void annotationPoinCut(){};


    @After("annotationPoinCut()")    // 注解声明一个建言,并使用PointCut定义的切点
    public void after(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        Action action = method.getAnnotation(Action.class);

        System.err.println("注解式拦截"+action.name());    // 通过反射可以获得注解属性

    }

    @Before("execution(* com.example.demo.aop.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.err.println("方法规则式拦截"+method.getName());
    }
}

配置类

使用EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持


package com.example.demo.aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

 
@Configuration
@ComponentScan("com.example.demo.aop")
@EnableAspectJAutoProxy
public class AopConfig {

}

启动

package com.example.demo;

import com.example.demo.aop.AopConfig;
import com.example.demo.aop.DemoAnnotationService;
import com.example.demo.aop.DemoMethodService;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {


        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);


        DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);

        DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);

        demoMethodService.add();

        demoAnnotationService.add();

        context.close();
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值