【spring源码学习】spring的AOP面向切面编程的实现解析

一:Advice(通知)
(1)定义在连接点做什么,为切面增强提供织入接口。在spring aop中主要描述围绕方法调用而注入的切面行为。
(2)spring定义了几个时刻织入增强行为的接口
??=>org.springframework.aop.BeforeAdvice
???org.springframework.aop.MethodBeforeAdvice
??=>org.springframework.aop.AfterAdvice
???org.springframework.aop.AfterReturningAdvice
??=>org.springframework.aop.ThrowsAdvice

二:PointCut(切点)
(1)决定Advice应该作用那些连接点。也就是说通过PointCut来定义需要增强的方法集合。
(2)spring定义的PointCut的接口
??=>org.springframework.aop.Pointcut
??=>org.springframework.aop.TruePointcut
??=> org.springframework.aop.support.JdkRegexpMethodPointcut
(3)相关接口。PointCut接口会返回两个对象,一个ClassFilter,一个是MethodMatcher
??=>org.springframework.aop.ClassFilter    
??=>org.springframework.aop.TrueClassFilter

??=>org.springframework.aop.MethodMatcher  匹配当前方法是否需要执行增强逻辑,也就是是否需要执行Advice接口的方法。
??=>org.springframework.aop.TrueMethodMatcher

三:通知器皿(Advisor)
??(1)完成对目标方法的切面增强设计(advice)和关注点的设计(PoinCut)以后,需要一个对象把他们结合起来,完成这个作用的就是(Advisor)
??(2)spring定义的Advisor接口
??=>org.springframework.aop.Advisor
??=>org.springframework.aop.support.DefaultPointcutAdvisor

??(3)Advisor的控制器的接口
??=>org.springframework.aop.framework.adapter.AdvisorAdapter
??=>org.springframework.aop.framework.adapter.AfterReturningAdviceAdapter  目标方法执行完执行该增强的控制器
??=>org.springframework.aop.framework.adapter.MethodBeforeAdviceAdapter  目标方法未执行前执行该增强的控制器
??=>org.springframework.aop.framework.adapter.ThrowsAdviceAdapter   目标方法执行过程抛出异常执行该增强的控制器

四:springAop的相关
??(1)springAop的核心技术是动态代理。动态代理的技术是jdk的一个特征。
??(2)springAop的代理对象生成案例
????=>org.springframework.aop.framework.ProxyFactoryBean
????=>org.springframework.aop.framework.ProxyFactory

五:ProxyFactoryBean的工作流程。
(1)实现FactoryBean接口的类,在想IOC容器申请bean的时候,其实返回的是该类执行getObject()方法的返回。
(2)ProxyFactoryBean的getObject()方法返回的是目标对象的代理对象。
??其执行过程
??=>根据配置的interceptorNames的属性值先初始化代理增强的链子.根据interceptorNames从IOC容器中得到增强类的bean,然后判断其类型,形成DefaultPointcutAdvisor对象。
??=>根据配置的targetName属性值从IOC容器中得到目标对象的bean,形成一个SingletonTargetSource对象。
??=>将其本身作为一个aop代理对象创建的数据配置类,创建一个动态代理对象,返回给ioc容器申请。
(3)在执行目标对象的方法过程中,会根据执行的方法的对象,从代理链子里找到所有的Advisor对象,然后利用其属性Pointcut对象获取ClassFilter, MethodMatcher来判断当前Advisor是否要执行。如果执行,则加入执行代理链子中。以jdk动态代理为例子,是org.springframework.aop.framework.JdkDynamicAopProxy类中invoke(Object proxy, Method method, Object[] args)方法中这句代码List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);。该句代码中this.advised其实就是ProxyFactoryBean本身。

六案例

一:Advice的对象

package com.mobile.thinks.aop.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class LoginBeforeAdvice implements MethodBeforeAdvice{

    @Override
    public void before(Method method, Object[] args, Object target)throws Throwable {
        System.out.println("LoginBeforeAdvice.before()执行方法为==>"+method.getName());
        System.out.println("LoginBeforeAdvice.before()执行参数为==>"+args);
        System.out.println("LoginBeforeAdvice.before()执行的目标为==>"+target.getClass());
    }

}

二:目标对象

package com.mobile.thinks.service.impl;

import java.util.Date;

import org.springframework.stereotype.Service;

import com.mobile.thinks.entity.User;
import com.mobile.thinks.service.UserInfoService;

@Service(value="userInfoServiceImpl")
public class UserInfoServiceImpl implements UserInfoService{

    @Override
    public User loginByUserNameAndPassWord(String userName, String passWord) {
        User user=new User();

        user.setAddress("三门峡");
        user.setAge(28);
        user.setCreateTime(new Date());
        user.setName(userName);
        return user;
    }

}

三:配置文件

 <!-- 测试ProxyFactoryBean -->
       <!--定义一个advice  -->
       <bean name="loginBeforeAdvice" class="com.mobile.thinks.aop.advice.LoginBeforeAdvice" />
    <!-- 定义FactoryBean -->
    <bean name="userInfoService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 要代理的目标对象,在ioc容器中的名字 -->
        <property name="targetName">
            <value>userInfoServiceImpl</value>
        </property>
        <!-- 要植入增强功能的advice在IOC容器中的名字 -->
        <property name="interceptorNames">
            <list><value>loginBeforeAdvice</value></list>
        </property>
    </bean>

七:spring内部基于该中方式实现动态代理的案例。spring提供的HttpInvoker远程调用.可以阅读该类getObject方法。实现对Facade接口代理

org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean

时间: 2024-10-27 06:37:22

【spring源码学习】spring的AOP面向切面编程的实现解析的相关文章

重新学习之spring第二个程序,配置AOP面向切面编程

第一步:在配置好的ioc容器的基础上,导入面向切面编程所需要的jar包 (本案例用的是spring3.2.4,由于spring3.2.4的官网jar包中不再有依赖包,所以依赖包都是从网上找的) 第二步:配置applicationContext.xml(包括ioc对象配置,以及面向切面编程的相关配置) 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.sp

Spring源码学习笔记(7)

Spring源码学习笔记(七) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门 写前说句话, 开篇不尴尬 ---- 接下的这一篇当中, 我们将来回顾 Spring 中 AOP 功能的实现流程.  早上精力充沛, 开始新一天的学习 \(^o^)/~ 接触过 Spri

Spring源码学习笔记(6)

Spring源码学习笔记(六) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. 上一篇中我们梳理到 Spring 加载 XML 配置文件, 完成 XML 的解析工作,接下来我们将进入 Spring 加载 bean 的逻辑. 我们使用 Spring 获取 XML

Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设计精巧,代码优美,值得每一名开发人员学习阅读. 在我最开始学习javaEE时,第一次接触Spring是从一个S(Struts)S(Spring)H(Herbinate)的框架开始.由java原生开发到框架开发转换过程中,那时我的印象里Struts负责控制层,herbinate负责数据层,而Sprin

Spring源码学习笔记(3)

Spring源码学习笔记(三) 前言----     最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. DispatcherServlet 实现核心功能 和普通的 Servelt 类一样, DispatcherServlet 中的 doGet() 和 doPost() 方法

Spring源码学习的初步体会

Spring源码学习的初步体会: 深入学习和巩固java的基础知识,其中的java知识范围全部,可以边研究源码边巩固复习基础知识 体会其中用到的设计思想:其中包含的设计原则和设计模式. 加深对spring的理解,在业务开发中使用spring更容易和深入,提高了生产率.

Spring源码学习笔记(5)

Spring源码学习笔记(五) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门 写下一句话,开篇不尴尬  ----  上篇文章中梳理到 Spring 加载资源文件后开始解析 Bean, 现在我们从两个解析函数 parseDefaultElement() 和 par

Spring 源码学习(二) IOC容器启动过程

这一节主要是记录一下Spring Ioc 容器的启动过程. Spring 的 Ioc 容器是怎么被加载和使用的? web容器为它提供了宿主环境 ServlectContext,  Tomcat 启动时会读取web.xml. 并且实例化web.xml中配置的ContextLoaderListener ,下面看一下ContextLoaderListener的创建过程: 在实例化ContextLoaderListener 之后,通过接口回调执行ContextLoaderListener 类中的cont

浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring框架的,这就说明你有权选择是否要用AOP来完成一些业务. AOP面向切面编程,通过另一种思考的方式,来弥补面向对象编程OOP当中的不足,OOP当中最重要的单元是类,所以万物皆对象,万物皆是 对象类.而在AOP的模块单元中,最基础的单元是切面,切面对切点进行模块化的管理. 最后再提一句:Spring当