`
jianchen
  • 浏览: 342278 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring学习之第三篇

阅读更多

AOP技术
使用jdk提供的动态代理技术,可以实现对横向性切点关注.实现对目标对象的方法拦截,做出相应的处理.动态代理请参见前面的博文.使用jdk提供的代理类,要求目标对象要实现相应的接口才行。

但在实际应用中,很多类其实并没有实现接口。那么我们又如何来实现拦截技术呢?
可以使用CGlib包提供的代理来实现。
注:CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
示例代码如下:

public class CGLIBProxy implements MethodInterceptor{
        private Object targetObject;//代理的目标对象
        public Object createProxyInstance(Object targetObject){
                this.targetObject = targetObject;
                Enhancer enhancer = new Enhancer();//该类用于生成代理对象
`               enhancer.setSuperclass(this.targetObject.getClass());//设置父类
                enhancer.setCallback(this);//设置回调对象为本身
                return enhancer.create();//返回代理对象
        }

        public Object intercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy)throws Throwable{
                Object result;//环绕通知
                //....preAdvice()--->前置通知
                try{
                        result = methodProxy.invoke(this.targetObject,args);
                        //....afterAdvice()--->后置通知
                }catch(RuntimeException e){
                        //exceptionAdvice()--->异常通知
                }finally{
                        //finallyAdvice()--->最终通知
                }
                return result;
        }
}

 

AOP中的概念:
Aspect(切面):指横切性关注点的抽象即为切面,它与类相识,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象。

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器。

Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义。匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。

Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知。

Target(目标对象):代理的目标对象

Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入。

Introduction(引入):在不修饰类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或field。

使用Spring进行面向切面(AOP)编程
要进行AOP编程,首先我们要在spring的配置文件中引入AOP命名空间:

<?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-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
<aop:aspectj-autoproxy/>
....//当然必须把bean和拦截器bean在配置文件中指定,交由spring容器进行管理
....
</beans>

注:蓝色部分启动对@Aspect注解的支持

spring提供了两种切面使用方式,实际工作中我们可以选用其中一种:
★基于XML配置方式进行AOP开发。
★基于注解方式进行AOP开发。

基于注解的方式声明切面:使用到了AspectJ的支持。
示例:
@Aspect
public class LogPrint{
@Pointcut("execution( * cn.jianchen.service.impl..* .*(..))")    //蓝色的*号表示拦截的业务方法的返回值可以为任意类型,可以指定为具体的类型,如java.lang.String。浅绿色部分表示包名。后面跟了两个点号,表示下面的子包。后面紧跟着的星号表示匹配任意的类,也可以使用具体的类名。在后面的*号表示方法名,可以指定具体的类的方法名,用星号表示拦截任意方法。后面的括号表示方法的参数。其中的两点表示参数可有可无。
        private void anyMethod(){}//声明了一个切入点

@Before("anyMethod() && args(userName)") //定义前置通知。这里还附加上了方法参数的限制,也就是说只会对具有唯一一个字符串类型参数的方法进行执行前置通知的拦截。同时获得传递进来的参数
        public void daAccessCheck(String userName){
        }
@AfterReturning( pointcut="anyMethod()",returning="revalue")//定义后置通知,同时会把业务方法返回结果传到revalue中。业务方法返回参数类型需要和通知方法中的参数类型一致。
        public void doReturnCheck(String revalue){
        }

@AfterThrowing (pointcut="anyMethod()",throwing="ex")//定义异常通知
        public void doExceptionAction(Exception ex){
        }

@After ("anyMethod()")//定义最终通知
public void doReleaseAction(){
        }

@Around ("anyMethod()")//环绕通知
public Object doBasicProfiling(ProceedingJoinPoint pjp){ //环绕通知的固定声明,返回类型和参数类型不可以被修改,其他部分不要求
                return pjp.proceed();//必须调用该方法,会导致先执行后面的切面,切面都执行完毕后,才执行业务bean的方法。
        }
}

注: 实现了环绕通知,完全可以代替使用上面的四种通知。只需要在pjp.proceed()方法前后加上相应的代码,便可以实现前置通知,后置通知,异常通知,最终通知。

基于XML配置方式声明切面
<bean id="personService" class="cn.jianchen.service.PersonServiceBean"/>
<bean id="log" class="cn.jianchen.service.LogPrint"/> //具体的拦截器
<aop:config>
    <aop:aspect id="myAspect" ref="log" > //定义一个切面
         <aop:pointcut id="mycut" expression="execution(* cn.jianchen.service.PersonServiceBean.*(..))"/>
         <aop:before pointcut-ref="mycut" method="doAccessCheck"/>
         <aop:after-returning pointcut-ref="mycut" method="doReturnCheck"/>
         <aop:after-throwing pointcut-ref="mycut" method="doExceptionAction"/>
         <aop:after pointcut-ref="mycut" method="doReleaseAction"/>
         <aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
    </aop:aspect>
</aop:config>

切入点表达式的书写:
expression="execution(* cn.jianchen.service.PersonServiceBean.*(..))"
返回值类型:可以用expression="execution(!void cn.jianchen.service.PersonServiceBean.*(..))"来表示排除返回值类型为void的方法,即不拦截此类方法。
拦截的方法参数expression="execution(* cn.jianchen.service.PersonServiceBean.*(String,.. ))"表示拦截方法的第一个参数类型为String,后面的参数无所谓的方法。
返回值类型:expression="execution(java.lang.String cn.jianchen.service.PersonServiceBean.*(..))"表示只拦截返回为string类型的方法。

spring的AOP机制:
如果满足拦截条件的类实现了接口。则spring使用jdk提供的动态代理创建代理对象实现aop。
如果满足拦截条件的类未实现接口。则spring使用cglib提供的方法实现代理的对象的创建,实现aop。

分享到:
评论

相关推荐

    学习笔记:尚硅谷Spring6基础篇

    - **一站式服务**:Spring框架不仅可以整合各种企业应用的开源框架和优秀的第三方类库,还提供了丰富的项目支持,几乎可以满足所有企业级应用的需求。 #### 二、Spring模块组成 Spring框架由多个模块组成,每个...

    SpringCloud学习第一天,helloWorld

    在本篇【SpringCloud学习第一天,helloWorld】的教程中,我们将初步接触并了解Spring Cloud这一微服务框架,以及如何创建一个基本的“Hello, World”应用。首先,我们需要理解Spring Cloud的核心概念和作用。 ...

    JAVA spring 系列案例50个和学习资料

    Spring系列第3篇:Spring容器基本使用及原理。Spring系列第4篇:xml中bean定义详解(-)Spring系列第5篇:创建bean实例这些方式你们都知道?Spring系列第6篇:玩转bean scope,避免跳坑里!Spring系列第7篇:依赖注入...

    spring-security3 入门篇

    - **OAuth2集成**: 如何使用Spring Security与OAuth2结合,实现第三方登录功能。 - **CORS支持**: 设置跨域请求的安全策略,允许不同源的Web应用进行交互。 - **国际化的错误处理**: 如何定制Spring Security的...

    jee、spring、spring mvc、mybatis 学习(五)

    在本篇【jee、spring、spring mvc、mybatis 学习(五)】中,我们将深入探讨四个关键的Java企业级开发技术:Java EE(Java Enterprise Edition)、Spring框架、Spring MVC以及MyBatis。这些技术是现代Java Web应用...

    spring5学习笔记

    "3、HelloSpring.md"通常作为Spring入门的第一个示例,展示了如何创建一个简单的Spring应用,帮助初学者快速上手。 综上所述,Spring5的学习涵盖了从基础到高级的各种主题,包括依赖注入、面向切面编程、事务管理、...

    Spring Boot 初探 | 第一篇:第一个Spring Boot程序(示例程序)

    它集成了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、Quartz 等,让你可以“零”配置启动项目。在本篇中,我们将探索如何创建并运行你的第一个 Spring Boot 应用程序。 1. **快速入门:创建项目** ...

    使用spring3D绘图

    "使用Spring3D绘图"这个主题则聚焦于Spring框架的一个特定应用,即如何利用Spring来创建三维图形和图表。在本篇文章中,我们将深入探讨这一主题,了解Spring3D的基本概念、相关技术以及如何通过实际代码实现图表的...

    《精通Spring2.X企业应用开发详解》随书源码1-15章

    Spring容器高级主题 第6章 Spring AOP基础 第7章 基于@AspectJ和Schema的 第7章 AOP 第3篇 数据库访问 第8章 Spring对DAO的支持 第9章 Spring的事务管理 第10章 使用Spring JDBC访问数据库 ...

    struts2.1+spring2.5+hibernate3.3整合之第一步(spring2.5+hibernate3.3)

    本篇将详细阐述这三个组件的整合过程,以及各自的核心特性。 首先,Struts2是一个基于MVC设计模式的Web应用框架,它极大地简化了Java Web应用的开发。Struts2.1引入了拦截器(Interceptor)机制,使得业务逻辑和...

    spring-boot spring-security-oauth2 完整demo

    OAuth2是一种授权框架,它允许第三方应用在用户授权的情况下,访问特定的资源。在Web服务中,OAuth2常用于实现单点登录(SSO,Single Sign-On)和API访问控制,确保数据安全的同时提供便捷的用户体验。 在这个完整...

    咕泡学院_Tom_JavaVIP课程_深入分析Spring源码(第一阶段)1

    4. **JDBC 支持**:Spring 提供了一个简单的 JDBC 抽象层,减少了直接使用 JDBC 的繁琐,同时支持与第三方持久层框架(如 Hibernate、JPA)的集成。 5. **Java EE 整合**:Spring 可以很好地与 Java EE 技术(如 ...

    Spring 注解学习手札(一) 构建简单Web应用

    在本篇《Spring注解学习手札(一)构建简单Web应用》中,我们将深入探讨如何使用Spring框架的注解来构建一个基本的Web应用程序。Spring框架是Java开发中的核心工具,尤其在企业级应用中广泛应用。它简化了依赖注入、...

    spring3--最小系统

    标题“spring3--最小系统”指的是Spring框架的第三版中构建最小化但功能完整的应用程序的方法。这个主题主要围绕Spring MVC 3展开,Spring MVC是Spring框架的一个模块,专门用于处理Web应用程序的请求-响应模式。在...

    Spring全家桶课程 基础篇:Spring MVC快速开发 的源码

    内容概要:该资源是Spring全家桶视频课程的第二部分Spring MVC的源码,其对于Spring的最常用的基本功能,如:表单、国际化、过滤器、拦截器、log等都使用案例进行了说明,并且在最后通过一个贯穿前、中、后台的案例...

    spring doc3

    标题“spring doc3”指的是与Spring框架相关的文档资料,很可能是指Spring框架的第三部分文档或者更新版本的介绍。描述中的“博文链接:https://a330488020.iteye.com/blog/1633334”指向了一个ITeye上的博客文章,...

    spring中所需要的知识点及学习方向文档

    基本的jar包包括spring.jar,以及针对特定功能如AOP、JDBC等的第三方库。例如,如果使用AOP,还需包含aspectjweaver.jar和aspectjrt.jar,而使用JSR-250注解则需要common-annotations.jar。 Spring的配置文件通常...

    Spring Web Service 实战篇(1)

    5. `lib`:这是一个存放项目依赖库的目录,包含Spring Web Service框架和其他必要的第三方库,如HTTP客户端库、XML解析库等。这些库使得项目能够正确运行和提供服务。 综上所述,这个实战教程将引导我们通过Ant构建...

Global site tag (gtag.js) - Google Analytics