`

[SXT][WY]Spring07 Spring_AOP示例

阅读更多

===========   用 Annotation的方式 实现 AOP  =================

 

1、spring依赖库
    * SPRING_HOME/dist/spring.jar
    * SPRING_HOME/lib/jakarta-commons/commons-logging.jar
    * SPRING_HOME/lib/log4j/log4j-1.2.14.jar
    * SPRING_HOME/lib/aspectj/*.jar

 

2、采用Aspect定义切面

3、在Aspect定义Pointcut和Advice

4、启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中

注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点
即Advice中通过方法名引用这个切人点

 

AOP术语(对应下面的例子 理解):
    * Cross cutting concern   // 做检查安全性这个需求 就是 一个 横切关注点
    * Aspect    // SecurityHandler类 就是一个 方面aspect
    * Advice    // checkSecurity()方法
    * Pointcut    // add*方法  delete*方法 等等的方法
    * Joinpoint    //
    * Weave    // advice 应用到对象的过程 就叫做weave
    * Target Object    // UserManagerImpl
    * Proxy    // 本例中,从ioc容器中 拿出的usermanager类,就是代理
    * Introduction   // 了解一下,作用是 动态添加方法

 

本节的例子:

 

UserManager.java

public interface UserManager {

    public void addUser(String username, String password);
   
    public void deleteUser(int id);
   
    public void modifyUser(int id, String username, String password);
   
    public String findUserById(int id);
}


UserManagerImpl .java
public class UserManagerImpl implements UserManager {

    public void addUser(String username, String password) {
        System.out.println("-------UserManagerImpl.addUser()----------");
    }

    public void deleteUser(int id) {
        System.out.println("-------UserManagerImpl.deleteUser()----------");
    }

    public String findUserById(int id) {
        System.out.println("-------UserManagerImpl.findUserById()----------");
        return null;
    }

    public void modifyUser(int id, String username, String password) {
        System.out.println("-------UserManagerImpl.modifyUser()----------");
    }
}

 

SecurityHandler.java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SecurityHandler {
   
    /**
     * 定义Pointcut,Pointcut的名称就是allAddMethod,此方法不能有返回值和参数,该方法只是一个
     * 标识
     *
     * Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint)
     */
    @Pointcut("execution(* add*(..)) || execution(* del*(..))")

     // 上面 这句话 很重要:意思是

     //  1、在ioc中配置的某一个类,如果这个类中包含有 和 add* 或 del* 匹配的方法,这个类就被代理。

     //  2、在ioc中配置的某一个类,如果这个类中 不包含 add* 或 del* 匹配的方法,ioc就不生成这个类的代理。
    private void allAddMethod(){};
   
    /**
     * 定义Advice,标识在那个切入点何处织入此方法
     */
    @Before("allAddMethod()")
    private void checkSecurity() {
        System.out.println("----------checkSecurity()---------------");
    }   
}

 

Client.java

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

    public static void main(String[] args) {
        BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 这里 从 ioc中拿出的 是 代理
        UserManager userManager = (UserManager)factory.getBean("userManager");
        // 这里 从 ioc中拿出的 是 代理
        UserManager um = (UserManager)factory.getBean("um");
       
        userManager.addUser("张三", "123");
       
        um.addUser("adf", "111");
    }
}

 

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"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    <aop:aspectj-autoproxy/>
    <bean id="securityHandler" class="test.aop.SecurityHandler"/>          
    <bean id="userManager" class="test.aop.UserManagerImpl"/> //  这里 拿出来就是 代理,因为这个类中,有和pointcut指定的方法 相匹配的方法
    <bean id="um" class="test.aop.UserManagerImpl"/>   // 这里 拿出来 就是 代理,因为这个类中,有和pointcut指定的方法 相匹配的方法
</beans>

 

PS:下面的地方 要好好理解

      @Pointcut("execution(* add*(..)) || execution(* del*(..))")

     // 上面 这句话 很重要:意思是

     //  1、在ioc中配置的某一个类,如果这个类中包含有 和 add* 或 del* 匹配的方法,这个类就被代理。

     //  2、在ioc中配置的某一个类,如果这个类中 不包含 add* 或 del* 匹配的方法,ioc就不生成这个类的代理。

 

 

===========   用 配置文件 的方式 实现 AOP  =================

 

这种方式 和 上一种方式,只有形式的差别,本质完全一样。

看完上个例子,很容易理解这个例子。

 

UserManager.java

UserManagerImpl .java

Client.java

这三个类 不用变。

 

SecurityHandler.java  类变的超级简单,之前annotation的作用 完全 转移到 applicationContext.xml中。

public class SecurityHandler {
   
    private void checkSecurity() {
        System.out.println("----------checkSecurity()---------------");
    }
   
}

 

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"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
   
    <bean id="securityHandler" class="test.aop.SecurityHandler"/>           
   
    <bean id="userManager" class="test.aop.UserManagerImpl"/>
   
    <aop:config>
        <aop:aspect id="security" ref="securityHandler">
            <aop:pointcut id="allAddMethod" expression="execution(* test.aop.UserManagerImpl.add*(..))"/>
            <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
        </aop:aspect>
    </aop:config>   

</beans>

 

粗体的部分,对照之前的 annotation 比较。完全 体现 了同样的信息。

 

===========  在advice方法中,如何拿到关于被代理类的更多信息  =================

 

import org.aspectj.lang.JoinPoint;

public class SecurityHandler {
   
    private void checkSecurity(JoinPoint joinPoint) {

        //  这里是 取得 参数
        Object[] args = joinPoint.getArgs();
        for (int i=0; i<args.length; i++) {
            System.out.println(args[i]);
        }
        //  这里是 取得 方法的名字
        System.out.println(joinPoint.getSignature().getName());
        System.out.println("----------checkSecurity()---------------");
    }
   
}

 

===========   CGLIB  =================

 

1、被代理的类 实现了某种 接口 的情况下,默认是jdk实现动态代理。

     被代理的类 实现了某种 接口 的情况下,可以强制使用cglib来实现动态代理。

 

2、被代理的类 没有实现某种接口 的情况下,只能使用cglib来生成动态代理。

 

例子1(实现接口时,强制使用cglib代理):

<?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:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <bean id="securityHandler" class="com.bjsxt.spring.SecurityHandler"/>          
   
    <bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/>
   
    <aop:config>
        <aop:aspect id="security" ref="securityHandler">
            <aop:pointcut id="allAddMethod" expression="execution(* com.bjsxt.spring.UserManagerImpl.add*(..))"/>
            <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
        </aop:aspect>
    </aop:config>   
</beans>

 

注意粗体的语句,说明了:代理类的生成 强行指定cglib生成。在client.java类中,断点调试可以清楚的看到效果。

 

例子2(没有实现接口时,spring会自动的使用cglib 来生成代理):

 

这里需要做的 只是 1、把 UserManager.java接口去掉。2、把强行指定那句化删掉  其他不变。

 

spring 回自动判断 使用 jdk动态代理 还是 cglib代理。

 

当然 推荐使用的 还是 jdk动态代理了。

分享到:
评论

相关推荐

    11spring4_aop3.rar

    http://www.springframework.org/schema/aop/spring-aop.xsd"&gt; &lt;bean id="userService" class="cn.sxt.service.impl.UserServiceImpl"&gt; &lt;bean id="log" class="cn.sxt.log.Log"/&gt; &lt;aop:aspectj-autoproxy/&gt; ...

    sxt.rar_sxt_手写_手写 识别_手写体 识别_文字识别

    《手写体文字识别技术深度解析》 在数字化时代的今天,手写体文字识别技术扮演着日益重要的角色,尤其在教育、文档管理、个人笔记数字化等领域。本文将深入探讨一个基于C++实现的手写体文字识别系统,以及相关的新...

    Spring 3.0 新特性

    **Spring 3.0新特性详解** Spring框架作为Java企业级应用开发的基石,自发布...文件`SXT_Spring3_02`和`SXT_Spring3_01`可能涵盖了Spring 3.0的基础概念和使用方法,对于深入理解和使用这个版本的Spring框架至关重要。

    SXT.rar_DELPHI 摄像头_avicap32

    "SXT.rar_DELPHI 摄像头_avicap32"这个压缩包文件提供了一个使用Delphi编程语言进行摄像头捕捉的解决方案。Delphi是一种强大的对象 Pascal 编程环境,常用于快速开发Windows桌面应用。在这个项目中,开发者可以利用...

    sxt.rar_摄像头 监控_视频 监控

    标题 "sxt.rar_摄像头 监控_视频 监控" 涉及的主要知识点是摄像头视频监控系统,其中包含了多个关键组件和编程模块。这是一个用于捕获和处理摄像头视频流的应用程序,可能用于安全监控或者类似目的。下面将详细阐述...

    sxt.rar_VC控制_vc 摄像头_摄像机 控制

    标题“sxt.rar_VC控制_vc 摄像头_摄像机 控制”暗示了这是一个基于VC++的项目,目的是实现对摄像头和摄像机的远程操控。描述中提到的功能包括选择不同线路的摄像头、执行上/下/左/右探视、镜头拉伸以及自动巡视,...

    sxt.rar_DELPHI 摄像头_delphi 拍照

    在本文中,我们将深入探讨如何使用Delphi编程语言来控制摄像头进行拍照,并对拍摄的图片进行简单的处理和保存。Delphi是一种强大的RAD(快速应用程序开发)工具,它提供了丰富的组件库和面向对象的编程环境,使得...

    spring AOP配置的几种方式

    本文主要介绍几种常见的Spring AOP配置方式,并通过具体的示例来说明每种配置的特点。 #### 二、AOP配置所需基本元素 配置AOP时需要以下三个基本元素: 1. **Advice**:这是实际执行的代码,即我们所说的“切面”...

    sxt.rar_dll_pb9_pb9示例

    "sxt.rar_dll_pb9_pb9示例" 提供了一个具体的例子,展示了如何在编程中使用DLL,特别是通过PB9(PowerBuilder 9)进行调用。PowerBuilder是一种强大的面向对象的开发工具,常用于构建数据库应用程序。 首先,我们...

    sxt.rar_PB拍照_PowerBuilder_pb 摄像头_pb摄像头软件_摄像头采集

    摄像头监控 pb V11.1=== === === === === = 首先感谢您使用本软件! 开发《摄像头监控》是因为本人有一天想用摄像头拍自己生活片段时, 苦于没有合适的软件完成这一工作,于是就萌生自己开发一个小软件的念头,...

    sxt.rar_分析_化学_水 visual basic_水 化学_水利

    随着科技的迅猛发展,信息化技术在各个领域中的应用变得越来越广泛。尤其在环境监测、水利工程和水质分析等专业领域,准确高效的数据处理是保证分析结果准确性、指导实际工作的关键。Visual Basic(VB),作为一种...

    sxt.rar_bmp_matlab采集图片

    在IT领域,尤其是在计算机视觉和图像处理中,"sxt.rar_bmp_matlab采集图片"这一主题涉及到如何使用MATLAB编程语言从摄像头捕获实时图像并将其保存为BMP格式的图片。MATLAB是一款强大的数学计算软件,同时也提供了...

    sxt.zip_VBa_摄像头

    标题 "sxt.zip_VBa_摄像头" 暗示了这个压缩包可能包含一个使用VBA(Visual Basic for Applications)编程实现的工具或代码,用于访问和操作摄像头。VBA是一种脚本语言,广泛应用于Microsoft Office套件中,如Excel、...

    SXT shell_SXTshell_

    【SXT Shell:一个自动化安装脚本的探索】 在IT行业中,自动化是提高效率的关键,尤其是在服务器管理和维护中。SXT Shell(SXTshell)是一个专门为实现自动化部署和配置而设计的脚本工具。它旨在简化系统管理员的...

    sxt.rar_录像_摄像头 录像_摄像头拍照_摄像头软件_本机录像软件

    在IT行业中,摄像头监控录像和拍照软件是常见的应用,尤其对于个人和小型企业而言,它们提供了安全监控和记录的功能。本篇文章将详细讲解基于标题"摄像头录像_摄像头拍照_摄像头软件_本机录像软件"以及描述中提到的...

    SXT_ksxt_

    很抱歉,但根据您给出的信息,标题"‘SXT_ksxt_’"和描述"‘加热后软件恶霸vi热v贵部 将二姑vUI热 进欧冠ire’"似乎包含了一些难以理解的词汇,它们可能不是标准的IT术语或者描述。标签"‘ksxt’"看起来像是简写或...

    sxt_api_14.jar

    sxt_api_14.jar,便于下载可以使用

    sxt.rar_sxt

    标题 "sxt.rar_sxt" 暗示我们正在处理一个RAR压缩文件,其中包含一个名为"sxt"的项目。这个文件很可能是一个使用Visual C++(VC++)编写的程序,目的是实现无须额外驱动就能访问和操作摄像头的功能。在Windows环境中...

    05spring4_di.rar

    &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c=...

    sxt.rar_c# 摄像头实例

    这个实例可能是一个基础的、可运行的代码示例,用于展示如何在C#环境中访问和操作摄像头设备。下面将详细讨论C#中摄像头控制的相关知识点。 在C#中,我们可以利用Windows Presentation Foundation (WPF)或Windows ...

Global site tag (gtag.js) - Google Analytics