zoukankan      html  css  js  c++  java
  • Spring_AOP

    Spring  AOP

    首先需要了解springAOP的一些重要概:

    1.切点:定义的就是为哪些方法增加功能  
    2.通知:定义的就是何时何事
    3.切面: 切面是一个类,包含了切点和通知的类
    4.织入:把切面整合到目标类的过程
    5.接入点:里面保存着当前执行的方法的信息

    springAOP利用了AspectJ个框架的配置方式.,就是里面的注解所以需要先导入一个jar包.

    具体实现:

    1.创建一个类,并spring注解标记.里面写原来执行的功能.

    @Service
    public class BookSericeImpl implements BookSerice {
        @Override
        public void addOne(BokBean bokBean) {
            System.out.println("执行逻辑:插入一本书");
        }
    
        @Override
        public void deletOne(Long bookId) {
            System.out.println("执行逻辑:删除一本书");
    
            //睡眠1秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    2.创建一个切面,即一个类,用@Aspect注解把这个类标记为切面,

    切点:  在切面里面为指定的类的方法添加切点.

    通知:  在围绕切点选择想要在什么时候增强什么功能.

    @Aspect
    @Component
    public class LogAspect {
    
        //1.切点
        //切点实际上就是一个表达式,规定为哪些方法做增强的表达式
        //表示Service类中的所有方法
        @Pointcut("execution(* com.lanou.demo.service.impl.*.*(..))")
        public void allServiceMethod(){
    
        }
    
        //2.通知
        //前置通知
        @Before("allServiceMethod()")     //该注解默认等于  @Before(value = "allServiceMethod()")
        public void before(JoinPoint jp){
    
            //JoinPoint接入点:
            //  可以根据需要获取下面的相关信息
    
            //获取被代理对象
            Object target = jp.getTarget();
            //获取方法签名
            Signature signature = jp.getSignature();
            //获取方法的参数
            Object[] args = jp.getArgs();
            System.out.println("方法之前执行");
        }
        //后置通知
        @After("allServiceMethod()")
        public void after(JoinPoint jp){
    
            System.out.println("方法执行后");
        }
    
        //方法正常执行的通知
        //returning参数:接受参数
        @AfterReturning(value = "allServiceMethod()",returning = "value")
        public void returnLog(JoinPoint jp,Object value){
    
            System.out.println("方法正常执行"+value);
        }
    
        //异常通知
        @AfterThrowing(value = "allServiceMethod()",throwing = "ex")
        public void throwLog(JoinPoint jp,Exception ex){
            System.out.println("方法异常了");
        }
    
        //环绕通知 :相当于在原来方法周围添加功能.
        //ProceedingJoinPoint 是JoinPoint 的子类
        @Around("allServiceMethod()")
        public Object around(ProceedingJoinPoint jp){
            try {
                long start = System.currentTimeMillis();   //写在原来方法的前面相当于前置通知
                Object proceed = jp.proceed();   //这是执行的原来的方法
                long time = System.currentTimeMillis()-start;   //写在原来方法后面相当于后置通知
                System.out.println("运行时长"+time);
              return proceed;
    
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            return null;
        }
    }

    3.创建好切面后,需要在spring配置文件中配置aop,让spring根据注解自动加载切面

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
    
        <context:component-scan base-package="com.lanou.demo"/>
        <mvc:annotation-driven/>
        <aop:config>
            
            <aop:pointcut id="service" expression="execution(* com.lanou.demo.service.impl.*.*(..)))"/>
            <aop:aspect ref="logAspect" order="1">
                <aop:before method="before" pointcut-ref="service"/>
                
            </aop:aspect>
            
        </aop:config>
    
    
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--配置可以根据注解自动加切面的功能-->
        <!--第一种的配置方式:常用-->
    <aop:aspectj-autoproxy/>
    <!--第二种配置方式: 这种配置方式不需要再用注解标记,而是在这里面指定要加载的类和方法 里面的参数跟注解方式注解的参数对应. --> <!--<aop:config>--> <!--<aop:pointcut id="service" expression="execution(* com.lanou.demo.service.impl.*.*(..)))"/>--> <!--<aop:aspect ref="logAspect" order="1">--> <!--<aop:before method="before" pointcut-ref="service"/>--> <!--</aop:aspect>--> <!--</aop:config>--> </beans>

    4.调用bookserviceImpl中的方法,(这里用spring测试类测试)

    //spring测试类注解.
    @RunWith(SpringJUnit4ClassRunner.class)
    //加载spring的配置文件
    @ContextConfiguration("classpath:application-context.xml")
    public class BookSericeImplTest {
    
        @Resource
        private BookSerice bookSerice;
    
        @Test
        public void text1() {
            
    //调用原来方法
    this.bookSerice.deletOne(33L); } }

    执行结果如下:

    会发现为类或方法配置好切点后,当执行该方法时,spring会自动为该方法添加增强的功能.

    INFO: HV000001: Hibernate Validator 6.0.16.Final
    方法之前执行
    执行逻辑:删除一本书
    运行时长1002
    方法执行后
    方法正常执行null
    
    Process finished with exit code 0
  • 相关阅读:
    pcs7 opc 连接问题
    nuget 多个程序引用同一个库时,当个这个库更新时,引用的程序都要跟新,否则会在运行时出错
    nuget update FileConflictAction
    a
    C#版本
    .NET Framework版本与CLR版本之间的关系
    c# 将一种数组类型转成另一种数组类型
    tfs 清除缓存,在需要时
    java枚举和仿枚举
    java反射的用法
  • 原文地址:https://www.cnblogs.com/zhouchangyang/p/10922858.html
Copyright © 2011-2022 走看看