zoukankan      html  css  js  c++  java
  • spring(二) AOP注入

    AOP概念

    l  AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码

    l  经典应用:事务管理、性能监视、安全检查、缓存 、日志等

    l  Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码

    l  AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

    Aop的实现原理

    l aop底层将采用代理机制进行实现。

    专业术语

    1.target:目标类,需要被代理的类。例如:UserService

    2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法

    3.PointCut 切入点:已经被增强的连接点。例如:addUser()

    4.advice 通知/增强,增强代码。例如:after、before

    5. Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.

    6.proxy 代理类

    7. Aspect(切面): 是切入点pointcut和通知advice的结合

           一个线是一个特殊的面。

           一个切入点和一个通知,组成成一个特殊的面。

     

    1.execution()  用于描述方法 【掌握】

           语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

                  修饰符,一般省略

                         public             公共方法

                         *                    任意

                  返回值,不能省略

                         void               返回没有值

                         String             返回值字符串

                         *                   任意

                  包,[省略]

                         com.itheima.crm                   固定包

                         com.itheima.crm.*.service       crm包下面子包任意 (例如:com.itheima.crm.staff.service)

                         com.itheima.crm..                 crm包下面的所有子包(含自己)

                         com.itheima.crm.*.service..     crm包下面任意子包,固定目录service,service目录任意包

                  类,[省略]

                         UserServiceImpl                    指定类

                         *Impl                                   以Impl结尾

                         User*                                   以User开头

                         *                                         任意

                  方法名,不能省略

                         addUser                              固定方法

                         add*                                   以add开头

                         *Do                                     以Do结尾

                         *                                         任意

                  (参数)

                         ()                                        无参

                         (int)                                     一个整型

                         (int ,int)                               两个

                         (..)                                       参数任意

                  throws ,可省略,一般不写。

    2.within:匹配包或子包中的方法(了解)

           within(com.itheima.aop..*)

    3.this:匹配实现接口的代理对象中的方法(了解)

           this(com.itheima.aop.user.UserDAO)

    4.target:匹配实现接口的目标对象中的方法(了解)

           target(com.itheima.aop.user.UserDAO)

    5.args:匹配参数格式符合标准的方法(了解)

           args(int,int)

    6.bean(id)  对指定的bean所有的方法(了解)

           bean('userServiceId')

    =======================================================================================

    实例 :AOP基于xml配置开发

    UserAOP.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans 
     6         http://www.springframework.org/schema/beans/spring-beans.xsd
     7         http://www.springframework.org/schema/aop 
     8         http://www.springframework.org/schema/aop/spring-aop.xsd"> 
     9     
    10     <bean id="aspectUser" class="com.spring_aop1.AspectUser"></bean>
    11     <bean id="user" class="com.spring_aop1.User"></bean>
    12     
    13     <aop:config>
    14         <!-- expression="execution(返回值  包名.类名.方法名(参数类型))   id="任意":切入点名  -->
    15         <aop:pointcut expression="execution(* com.spring_aop1.*.*(..))" id="myPointcut"/>
    16         
    17         <aop:aspect ref="aspectUser">
    18             <aop:before method="password" pointcut-ref="myPointcut"/>
    19             <aop:after-returning method="after" pointcut-ref="myPointcut" returning="obj"/>
    20         <!-- <aop:around method="around" pointcut-ref="myPointcut" /> -->
    21             <aop:around method="aroundR" pointcut-ref="myPointcut" />
    22             
    23             <aop:after-throwing method="throwable" pointcut-ref="myPointcut" throwing="e"/>
    24         </aop:aspect>
    25         
    26     </aop:config>
    27     
    28 </beans>

    User.java

     1 package com.spring_aop1;
     2 
     3 public class User {
     4     
     5     private String str;
     6 
     7     public String getStr() {
     8         return str;
     9     }
    10     public void setStr(String str) {
    11         this.str = str;
    12     }
    13     
    14 
    15     public void insert(){
    16         System.out.println("insert====ok");
    17     }
    18     public void delete(){
    19         System.out.println("delete====ok");
    20     }
    21     public void update(){
    22         System.out.println("update====ok");
    23     }
    24     public void selete(){
    25         System.out.println("insert====ok");
    26     }
    27     
    28 }

    AspectUser.java

     1 package com.spring_aop1;
     2 
     3 import org.aspectj.lang.JoinPoint;
     4 import org.aspectj.lang.ProceedingJoinPoint;
     5 
     6 public class AspectUser {
     7     
     8     /**
     9      *  定义一个前置通知
    10      * */
    11     public void password(){
    12         System.out.println("前置通知:密码验证=====成功");
    13     }
    14     
    15     /**
    16      *  定义一个后置通知(可得方法返回值)
    17      *  @param jp  execution(void com.spring_aop.User.save())
    18      *  @param obj 
    19      * */
    20     public void after(JoinPoint jp,Object obj){
    21         String name = jp.getSignature().getName();
    22         
    23         System.out.println("后置通知:after获取一个返回值类型====切入点");
    24         System.out.println("after返回值信息为:"+name);
    25     }
    26     
    27     /**
    28      *  定义一个环绕通知
    29      *  @param pjp  execution(void com.spring_aop.User.save())
    30      * */
    31     public void around(ProceedingJoinPoint pjp) throws Throwable{
    32         System.out.println("环绕通知:around执行环绕通知前执行");
    33         pjp.proceed();
    34         System.out.println("环绕通知:around执行环绕通知后执行");
    35     }
    36     /**
    37      *  定义一个环绕通知(可得方法返回值)
    38      * @throws Throwable 
    39      * */
    40     public Object aroundR(ProceedingJoinPoint pjp) throws Throwable{
    41         System.out.println("环绕通知:around执行环绕通知前执行");
    42         Object obj = pjp.proceed();
    43         System.out.println("环绕通知:around执行环绕通知后执行");
    44         
    45         String s = pjp.getSignature().getName();
    46         System.out.println("around返回值的类型:"+obj+"  around返回方法名:"+s);
    47         return obj;
    48     }
    49     
    50     /**
    51      *  定义一个异常通知(可得方法返回值)
    52      * @throws Throwable 
    53      * */
    54     public void throwable(JoinPoint jp,Throwable e){
    55         System.out.println("到我这里来,说明 你发生了异常======");
    56     }
    57     
    58 }

    Test.java

     1 package com.spring_aop1;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class UserTest {
     7     
     8     public static void main(String[] args) {
     9         
    10         String str = "com/spring_aop1/UserAop.xml";
    11         ApplicationContext context = new ClassPathXmlApplicationContext(str);
    12         
    13         User user = (User)context.getBean("user");
    14         user.insert();
    15         
    16     }
    17     
    18 }

     实例 :AOP基于注解开发

    UserAOP.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:aop="http://www.springframework.org/schema/aop" 
     5     xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans 
     7         http://www.springframework.org/schema/beans/spring-beans.xsd
     8         http://www.springframework.org/schema/aop 
     9         http://www.springframework.org/schema/aop/spring-aop.xsd 
    10         http://www.springframework.org/schema/context 
    11         http://www.springframework.org/schema/context/spring-context.xsd">
    12     
    13     <!-- 自动扫描 配置  扫描所有注解 :使用注解注入 -->
    14     <context:component-scan base-package="com.spring_aop2"></context:component-scan>
    15     
    16     <!-- 添加AOP的注解扫描 -->
    17     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    18 
    19     
    20 </beans>

    User.java

     1 package com.spring_aop2;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component(value="user")
     6 public class User {
     7     
     8     private String str;
     9 
    10     public String getStr() {
    11         return str;
    12     }
    13     public void setStr(String str) {
    14         this.str = str;
    15     }
    16     
    17     public void insert(){
    18         System.out.println("insert====ok");
    19     }
    20     public void delete(){
    21         System.out.println("delete====ok");
    22     }
    23     public void update(){
    24         System.out.println("update====ok");
    25         int i = 1/0;
    26     }
    27     public void selete(){
    28         System.out.println("insert====ok");
    29     }
    30 
    31 }

    AspectUser.java

     1 package com.spring_aop2;
     2 
     3 import org.aspectj.lang.JoinPoint;
     4 import org.aspectj.lang.ProceedingJoinPoint;
     5 import org.aspectj.lang.annotation.After;
     6 import org.aspectj.lang.annotation.AfterReturning;
     7 import org.aspectj.lang.annotation.AfterThrowing;
     8 import org.aspectj.lang.annotation.Around;
     9 import org.aspectj.lang.annotation.Aspect;
    10 import org.aspectj.lang.annotation.Before;
    11 import org.aspectj.lang.annotation.Pointcut;
    12 import org.springframework.stereotype.Component;
    13 
    14 @Component("aspectUser") //组件
    15 @Aspect  //声明这是一个切面类
    16 public class AspectUser {
    17     
    18     /**
    19      *    <aop:pointcut
    20      *        expression="execution(* com.spring_aop2.*.*(..))"
    21      *    id="myPointcut" />
    22      * */
    23     @Pointcut("execution(* com.spring_aop2.*.*(..))")
    24     private void myPoint(){}
    25     
    26     /**
    27      *  定义一个前置通知
    28      * */
    29     @Before("execution(* com.spring_aop2.*.*(..))") //指向切入点的Id(私有方法的方法名)
    30     public void password(){
    31         System.out.println("前置通知:密码验证=====成功");
    32     }
    33     
    34     /**
    35      *  定义一个后置通知(可得方法返回值)
    36      *  @param jp  execution(void com.spring_aop.User.save())
    37      *  @param obj 
    38      * */
    39     @AfterReturning(value="myPoint()",returning="obj")
    40     public void after(JoinPoint jp,Object obj){
    41         String name = jp.getSignature().getName();
    42         
    43         System.out.println("后置通知:获取一个返回值类型====切入点");
    44         System.out.println("after返回值信息为:"+name);
    45     }
    46     
    47     /**
    48      *  定义一个环绕通知
    49      *  @param pjp  execution(void com.spring_aop.User.save())
    50      * */
    51     @Around("execution(* com.spring_aop.*.*(..))")
    52     public void around(ProceedingJoinPoint pjp) throws Throwable{
    53         System.out.println("环绕通知:around执行环绕通知前执行");
    54         pjp.proceed();
    55         System.out.println("环绕通知:around执行环绕通知后执行");
    56     }
    57     /**
    58      *  定义一个环绕通知(可得方法返回值)
    59      * @throws Throwable 
    60      * */
    61     public Object aroundR(ProceedingJoinPoint pjp) throws Throwable{
    62         System.out.println("环绕通知:around执行环绕通知前执行");
    63         Object obj = pjp.proceed();
    64         System.out.println("环绕通知:around执行环绕通知后执行");
    65         
    66         String s = pjp.getSignature().getName();
    67         System.out.println("around返回值的类型:"+obj+"  around返回方法名:"+s);
    68         return obj;
    69     }
    70     
    71     /**
    72      *  定义一个异常通知(可得方法返回值)
    73      * @throws Throwable 
    74      * */
    75     @AfterThrowing(value="myPoint()",throwing="e")
    76     public void throwable(JoinPoint jp,Throwable e){
    77         System.out.println("到我这里来,说明 你发生了异常======");
    78     }
    79     
    80 }

    Test.java

     1 package com.spring_aop2;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class UserTest {
     7     
     8     public static void main(String[] args) {
     9         
    10         String str = "com/spring_aop2/UserAop.xml";
    11         
    12         ApplicationContext context = new ClassPathXmlApplicationContext(str);
    13         
    14         User user = (User)context.getBean("user");
    15         user.insert();
    16         //user.update();
    17 
    18         
    19     }
    20     
    21 }
  • 相关阅读:
    数据库优化方案之分库分表
    聊聊ThreadLocal源码(基于JDK1.8)
    HashMap扩容死循环问题
    Synchronized偏向锁和轻量级锁的升级
    【Java并发编程之深入理解】Synchronized的使用
    ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock
    面试必备技能:HashMap哪些技术点会被经常问到?
    序列键生成器及单例多例模式
    Effective.Java第1-11条
    抽象工厂(AbstractFactory)模式
  • 原文地址:https://www.cnblogs.com/liuyangv/p/8508983.html
Copyright © 2011-2022 走看看