zoukankan      html  css  js  c++  java
  • JavaWeb_(Spring框架)认识Spring中的aop

    1、aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切

      

    2、Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他进行一些设置;

    3、Spring-aop是基于动态代理的 – 优先选用JDKProxy动态代理;

      a)Proxy动态代理:被代理的对象必须要实现接口;

      b)Cglib动态代理:被代理的对象不能被final修饰,基于继承;

    package com.Gary.service;
    
    public interface UserService {
    
        //
        void save();
        
        //
        void delete();
        
        //
        void update();
        
        //
        void find();
        
    }
    UserService.java
    package com.Gary.service;
    
    public class UserServiceImpl implements UserService{
    
        @Override
        public void save() {
            System.out.println("save()");
        }
    
        @Override
        public void delete() {
            System.out.println("delete()");
        }
    
        @Override
        public void update() {
            System.out.println("update()");
        }
    
        @Override
        public void find() {
            System.out.println("find()");
        }
    
    }
    UserServiceImpl.java
    package com.Gary.test;
    
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import com.Gary.service.UserService;
    import com.Gary.service.UserServiceImpl;
    
    //UserService代理类
    public class UserServiceProxy {
        //代理对象  UserServiceProxy
        //被代理对象  UserService
        public UserService getUserServiceProxy(UserService us) {
            return (UserService) Proxy.newProxyInstance(UserServiceProxy.class.getClassLoader(), 
                                   UserServiceImpl.class.getInterfaces(),
                                   new InvocationHandler(){
                                        @Override
                                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                            //增强代码
                                            System.out.println("开启事务");
                                            //需要调用原始的方法
                                            Object invoke = method.invoke(us, args);
                                            System.out.println("提交/回滚");
                                            
                                            return invoke;
                                        }
                                    });
        
        }
        
    }
    UserServiceProxy.java
    package com.Gary.test;
    
    import org.junit.Test;
    
    import com.Gary.service.UserService;
    import com.Gary.service.UserServiceImpl;
    
    public class AopTest {
    
        @Test
        public void Test1() {
            UserServiceProxy usProxy = new UserServiceProxy();
            UserService us = new UserServiceImpl();
            UserService us_PowerUp = usProxy.getUserServiceProxy(us);
            
            us_PowerUp.find();
            
        }
        
    }
    AopTest.java

    4、Spring aop相关名词说明

      代理写小学生暑假作业,3年级以下

      目标对象:UserService(小学生作业)

      被代理对象:被UserServiceProxy增强后的UserService(用你的知识去写的作业)

      JoinPoint、连接点、目标对象中,哪些方法会被拦截;save,delete,update,find (所有要写的作业:数学、语文、英语、王者荣耀代上王者)

        Pointcut切入点:筛选连接点,你最终要增强的方法;save,update,delete (小学生只让你给写数学语文英语,王者荣耀他自己上王者)

        Advice通知/增强:要执行的增强代码 (你用你N年积攒的知识去完成小学暑假作业)

        Introduction介入/引入:在执行时期动态加入一些方法或行为  

        Aspect切面:通知 + 切入点,通知应用到哪个切点

        target目标:被代理对象 (小学生的作业)

        weaving织入:把切面的代码应用到目标对象来创建新的代理对象的过程 (将你的脑子应用到写小学生的暑假作业上)

        proxy代理:把切面的代码应用到目标对象来创建新的代理对象(利用你的知识去完成作业)

    5、Spring aop配置:

      a)导包:

        i.基本包;

        ii.spring-aspects和spring-aop ;

        iii.aop联盟包 – aopalliance;

        iv.aop织入包 - aspectj.weaver;

      

      b)自定义通知,五种自定义通知类型:

        i.before 前置通知

        ii.after 最终通知(后置通知)

        iii.afterReturning 成功通知(后置通知)

        iv.afterThrowing 异常通知(后置通知)

        v.around 环绕通知

        在aop层创建一个MyAdvice.java自定义通知类

    package com.Gary.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    //自定义通知类
    public class MyAdvice {
    
        //before 前置通知  在目标方法前调用
        public void before() {
            System.out.println("before()");
        }
        
        //after 最终通知(后置通知)在目标方法后调用,无论是否出现异常都会执行 finally
        public void after() {
            System.out.println("after()");
        }
        
        //afterReturning 成功通知(后置通知)    在目标方法执行后,并执行成功,如果方法出现异常,则不会调用
        public void afterReturning(){
            System.out.println("afterReturning()");
        }
        
        //afterThrowing 异常通知(后置通知)   在目标方法执行出现异常的时候才会调用
        public void afterThrowing() {
            System.out.println("after()");
        }
        
        //around 环绕通知  需要我们手动调用目标方法,并且可以设置通知
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            
            System.out.println("around before");
            Object proceed = pjp.proceed();
            System.out.println("around after");
            return proceed;
        }
        
    }
    MyAdvice.java

      c)配置applicationContext.xml:

    <?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:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
            
            <!-- 目标对象 -->
            <bean name="userService" class="com.Gary.service.UserServiceImpl"></bean>
            
            <!-- 通知对象 -->
            <bean name="myAdvice" class="com.Gary.aop.MyAdvice"></bean>
            
            <aop:config>
                <!-- 切入点  expression 切入点表达式 可以配置要增强的方法
                                    public void com.Gary.service.UserServiceImpl.save()
                                    * com.Gary.service.*ServiceImpl.*(..)
                                   id 就是唯一标识
                -->
                <aop:pointcut expression="execution(* com.Gary.service.*ServiceImplabc.*(..))" id="servicePc"/>
                
                <!-- 切面 通知+切入点 -->
                <aop:aspect ref="myAdvice">
                    <!-- 通知类型 -->
                    <aop:before method="before" pointcut-ref="servicePc"/>
                    <!-- 最终通知 后置通知 -->
                    <aop:after method="after" pointcut-ref="servicePc"/>
                    <!-- 成功通知 后置通知 -->
                    <aop:after-returning method="afterReturning" pointcut-ref="servicePc"/>
                    <!-- 异常通知 后置通知 -->
                    <aop:after-throwing method="afterThrowing" pointcut-ref="servicePc"/>
                    <!-- 环绕通知 -->
                    <aop:around method="around" pointcut-ref="servicePc"/>
                </aop:aspect>
            </aop:config>
            
    </beans>
    applicationContext.xml
  • 相关阅读:
    反射创建对象
    DevExpress 日期输入框
    SsdlToSql10.tt文件内容
    ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
    DevExpress XtraCharts 图表导出PDF/XLS/JPEG
    Java中堆内存和栈内存详解(转)
    批量合并word文档
    java内部类总结(转)
    Java 之工厂方法和抽象工厂模式(转)
    Java GC 、引用
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/12005921.html
Copyright © 2011-2022 走看看