zoukankan      html  css  js  c++  java
  • spring学习日志三

    一、回顾

    1.1 依赖注入的方式。

    1. set方法来注入 <property name=”属性名” />
    2. 构造方法来注入<construtor-arg index=”” />

    1.2 依赖注入的数据类型。

    1. 基本类型和字符串 value
    2. 对象类型  ref       <bean></bean>
    3. 集合List set
    4. map类型 <entry key= value=>
    5. array类型

    1.3 引入属性文件.<context: property-placeholder     location=”classpath:*.properties”>

    1.4 自动注入。 autowire=”byName | byType | default | no ”

    1.5 bean的作用域  scope=”singleton | prototype”

    1.6 注解. @Repository (持久化) @Service (业务层) @Controller (控制层) @Component (组件) ,这四个功能都是一样的。

    @Autowired (自动注入 先按照类型注入,再按照名称注入)  @Resource (自动注入 按照名称先注入,再按照类型注入。如果没有起名,那么它的名称就是属性的名称。

     二、AOP面向切面编程

    Aop的前提:1.代理 2.AOP

    1.动态代理模式

    代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上.

     示例:

    创建接口ArithmeticCalculate

    public interface ArithmeticCalculate {
    
        /**
         * 加法
         * @param a
         * @param b
         * @return
         */
        public double add(double a,double b);
        /**
         * 减法
         * @param a
         * @param b
         * @return
         */
        public double sub(double a,double b);
        /**
         * 乘法
         * @param a
         * @param b
         * @return
         */
        public double mul(double a,double b);
        /**
         * 除法
         * @param a
         * @param b
         * @return
         */
        public double div(double a,double b);
    }

    创建接口的实现类

    package com.zhiyou100.ykq.aop.proxy;
    //1.使用代理(了解)  2.使用spring的aop。
    public class ArithmeticCalculateImp implements ArithmeticCalculate {
        //在每个方法中加入日志信息。
        @Override
        public double add(double a, double b) {
            double result=a+b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double sub(double a, double b) {
            double result=a-b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double mul(double a, double b) {
            double result=a*b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double div(double a, double b) {
            double result=a/b;
            System.out.println("result:"+result);
            return result;
        }
    
    }

    创建代理类并实现接口来代理需要被代理的对象

    //调用处理程序:InvocationHandler
    public class ArithmeticCalculateLogProxy implements InvocationHandler{
        //被代理的对象 明星
        private Object target;
        
        public ArithmeticCalculateLogProxy(Object target) {
            this.target = target;
        }
    
    
        /**
         * mothod: 正在被调用的方法
         * args: 正在执行的方法所需要的参数
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName=method.getName();
            System.out.println("the method "+methodName+" begin with "+Arrays.asList(args));
            //method:方法
            //target:目标对象
            Object result=method.invoke(target, args);//回调
            System.out.println("the method add end result:"+result);
            return result;
        }
        
        
        //得到代理对象。 经纪人
        public Object getProxy() {
             //loader: 得到代理对象的类加载器。  
             //interfaces: 代理对象 要代理的方法由哪些。
            //h: 当执行这些方法时,会调用该类中invoke方法
             return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    
    }

    测试

    public class Test {
        public static void main(String[] args) {
            ArithmeticCalculate target=new ArithmeticCalculateImp();//创建的王宝强
            
            ArithmeticCalculateLogProxy proxy=new ArithmeticCalculateLogProxy(target);
            
            ArithmeticCalculate p=(ArithmeticCalculate) proxy.getProxy(); //宋喆
            
            p.sub(15, 25);//1.首先执行invoke方法
            
            
        }
    }

    2.AOP模式

    2.1使用注解来完成

    加入依赖的jar包文件

    创建一个接口ArithmeticCalculate

    public interface ArithmeticCalculate {
    
        // 加法
        public double add(double a,double b);
        // 减法
        public double sub(double a,double b);
        // 乘法
        public double mul(double a,double b);
        // 除法
        public double div(double a,double b);
    }

    创建实现以上接口的类

    @Component
    public class ArithmeticCalculateImp implements ArithmeticCalculate {
        //在每个方法中加入日志信息。
        @Override
        public double add(double a, double b) {
            double result=a+b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double sub(double a, double b) {
            double result=a-b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double mul(double a, double b) {
            double result=a*b;
            System.out.println("result:"+result);
            return result;
        }
    
        @Override
        public double div(double a, double b) {
            if(b==2) {
                throw new RuntimeException("出错了");
            }
            double result=a/b;
            System.out.println("result:"+result);
            return result;
        }
    
    }

    创建一个切面类

    //切面类
    @Aspect
    @Component
    public class LogAspect {
        //*:通配的是访问修饰符
        //..:通配的是方法的参数,一般三个及以上
        //连接点(joinpoint)
        //Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
        //前置通知
        @Before(value="execution(* com.zhiyou100.xz.aspectj.*.*(..))")// 第一个*代表类,第二个*代表类中的方法
        public void aa(JoinPoint joinPoint) { //在ArithmeticCalculateImp中add方法前执行
            Object[] args=joinPoint.getArgs();
            String name=joinPoint.getSignature().getName();
            System.out.println("zhiyou-->the method "+name+" begin with"+Arrays.asList(args));
        }
        
        
        //@AfterReturning
        //后置通知
        @After(value="execution(* com.zhiyou100.xz.aspectj.*.*(..))")
        public void bb(JoinPoint joinPoint) {
            String name=joinPoint.getSignature().getName();
            //joinPoint.getTarget();
            System.out.println("zhiyou-->the method "+name+"end result:");
        }
        
        //返回通知
        @AfterReturning(value="execution(* com.zhiyou100.xz.aspectj.*.*(..))",returning="result")
        public void cc(Object result) {
            System.out.println("======"+result);
        }
        
        //异常通知
        @AfterThrowing(value="execution(* com.zhiyou100.xz.aspectj.*.*(..))",throwing="e")
        public void dd(Exception e) {
            System.out.println("异常了:"+e.getMessage());
        }
    }

     在spring的配置文件app.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"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       
            ">
          
          <!-- 包扫描 -->
          <context:component-scan base-package="com.zhiyou100.xz.aspectj"></context:component-scan>
            
            <!-- 开启切面注解 -->
            <aop:aspectj-autoproxy />
    </beans>

    测试

    public class Test {
           public static void main(String[] args) {
               ApplicationContext app=new ClassPathXmlApplicationContext("app.xml");          
               ArithmeticCalculate a=(ArithmeticCalculate) app.getBean("arithmeticCalculateImp");
                  a.div(10, 5);         
        }
    }

    2.2使用xml的方式来完成

     把第一种方式中的接口、接口的实现类以及切面类中的注解全部删除,然后新建spring的配置文件app2.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"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    
            ">
          <!-- 定义被通知的程序类 -->
          <bean id="ari" class="com.zhiyou100.xz.aspectj.xml.ArithmeticCalculateImp"></bean>
          
          <!-- 定义切面类的bean -->
          <bean id="logAspect" class="com.zhiyou100.xz.aspectj.xml.LogAspect"></bean>
          
          <!-- 配置切面 -->
          <aop:config>
                  <!-- 定义表达式切点 -->
                <aop:pointcut expression="execution(* com.zhiyou100.xz.aspectj.xml.*.*(..))" id="pointcut"/>
                  <!-- 定义切面 -->
                  <aop:aspect ref="logAspect">
                      <!-- 定义前置通知 -->
                      <aop:before method="aa" pointcut-ref="pointcut"/>
                      <aop:after method="bb" pointcut-ref="pointcut"/>
                      <aop:after-returning method="cc" pointcut-ref="pointcut" returning="result"/>
                      <aop:after-throwing method="dd" pointcut-ref="pointcut" throwing="e"/>
                  </aop:aspect>
          </aop:config>
    
    </beans>

    测试

    public class Test2 {
           public static void main(String[] args) {
               ApplicationContext app=new ClassPathXmlApplicationContext("app2.xml");
               
               ArithmeticCalculate a=(ArithmeticCalculate) app.getBean("ari");
                  a.div(10, 5);
               
        }
    }
  • 相关阅读:
    使用jsonEditor打造一个复杂json编辑器
    【原创】一次“诡异”的容器Unix Socket通信问题分析
    【原创】Ingress-Nginx-Controller的Metrics监控源码改造简析
    IDEA+DevTools实现热部署功能
    ElementUI按需引入各种组件
    vue-cli4.0更新后怎样将eslint关闭
    Mysql修改字段名、修改字段类型
    博客搬家CSDN
    如何优雅的处理Restful
    java系列之注解
  • 原文地址:https://www.cnblogs.com/sitian2050/p/11482029.html
Copyright © 2011-2022 走看看