zoukankan      html  css  js  c++  java
  • Spring -07 -AOP [面向切面编程]

    1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.
    1.1 引入xmlns:context ,指定扫描范围

    <context:component-scan base-package="com.advice,com.test"></context:component-scan>

    1.3 @Component

    1.4 相当于<bean/>

    1.5 如果没有参数,把类名首字母变小写,相当于<bean id=”别名”/>

    1.6 @Component(“自定义名称”)

    1.7     <aop:aspectj-autoproxy proxy-target-class="true"> </aop:aspectj-autoproxy>
                      <!--proxy-target-class="true"使用cglib动态代理;
                              否则使用jdk动态代理-->

    1.8  实现步骤:

    2.1  在spring 配置文件中设置注解在哪些包中 ,多个文件夹用分号隔开 ;以及加入属性:"  xmlns:context"" xsi:schemaLocation"

    <?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.advice,com.test"></context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> <!--proxy-target-class="true"使用cglib动态代理; 否则使用jdk动态代理--> </beans>

    2.2在Demo 类中添加@Componet

      2.2.1在方法上添加@Pointcut(“”) 定义切点

    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Component
    public class demo {
        @Pointcut("execution(* com.test.demo.demo1())")
        public void demo1(){
     //       int i=5/0;
            System.out.println("demo1");
        }
    }

    2.3在通知类中配置 --@Component @Aspect 都不能剩下!!

      2.3.1@Component 类被spring 管理
        @Aspect 相当于<aop:aspect/>表示通知方法在当前类中;

    package com.advice;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class MyAdvice {
        @Before("com.test.demo.demo1()")
        public void mybefore(){
            System.out.println("前置通知!!");
        }
        @After("com.test.demo.demo1()")
        public void myafter(){
            System.out.println("后置通知");
        }
        @AfterThrowing("com.test.demo.demo1()")
        public void mythrow(){
            System.out.println("异常通知");
        }
        @Around("com.test.demo.demo1()")
        public Object myArround(ProceedingJoinPoint p) throws
                Throwable {
            System.out.println("环绕-前置");
            Object result = p.proceed();
            System.out.println("环绕-后置");
            return result;
        }
    }

    2.4 编写test测试类并进行测试

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test {
        public static void main(String[] args) {
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    // 输出Spring自动加载的所有类
    //      String[] names = ac.getBeanDefinitionNames();
    //        for(int i=0;i< names.length;i++)
    //            System.out.println(names[i]);
            demo d=ac.getBean("demo",demo.class);
            d.demo1();
    
        }
    }
    myAdvice
    demo
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalRequiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.aop.config.internalAutoProxyCreator
    org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
    org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
    环绕-前置
    前置通知!!
    demo1
    环绕-后置
    后置通知
    View Code(测试结果)

    八.代理设计模式

    1.设计模式:前人总结的一套解决特定问题的代码.
    2.代理设计模式优点:
    2.1保护真实对象
    2.2让真实对象职责更明确.
    2.3扩展
    3.代理设计模式
    3.1真实对象.(老总)
    3.2代理对象(秘书)
    1.抽象对象(抽象功能),谈小目标


    九. 静态代理设计模式

    2.由代理对象代理所有真实对象的功能.
    2.1自己编写代理类

    2.2每个代理的功能需要单独编写
    3.静态代理设计模式的缺点:
    1.当代理功能比较多时,代理类中方法需要写很多.


    十. 动态代理


    2.为了解决静态代理频繁编写代理功能缺点.
    3.分类:
    3.1JDK 提供的cglib 动态代理


    十一. JDK 动态代理


    1.和cglib 动态代理对比
    1.1优点:jdk 自带,不需要额外导入jar
    1.2缺点:
    1.2.1真实对象必须实现接口
    1.2.2利用反射机制.效率不高.
    2.使用JDK 动态代理时可能出现异常ClasscastException : cat not cast to xxx.
    出现原因:希望把接口对象转换为具体真实对象

     


    十二: cglib 动态代理


    1.cglib 优点:
    1.1基于字节码,生成真实对象的子类.
    1.1.1运行效率高于JDK 动态代理.
    1.2不需要实现接口
    2.cglib 缺点:
    2.1非JDK 功能,需要额外导入jar
    3.使用spring aop 时,只要出现Proxy 和真实对象转换异常
    3.1设置为true 使用cglib
    3.2设置为false 使用jdk(默认值)

    <aop:aspectj-autoproxy
    proxy-target-class="true"></aop:aspectj-autoproxy>
  • 相关阅读:
    斜率DP小结
    CF 1059 D Nature Reserve(double 精度问题)
    ZOJ 3747 Attack on Titans(DP+思维)
    BZOJ 1933 Bookcase 书柜的尺寸
    异或的一些性质
    (学习5 分治思想)最短对的问题
    (学习4)二分归并排序
    mac上git与github的联动
    (学习3)二分法与二叉查找树
    (学习2)Floyd和Dijkstra算法
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/10102709.html
Copyright © 2011-2022 走看看