1. 程式人生 > >Spring原始碼解讀以及Spring整體結構淺析

Spring原始碼解讀以及Spring整體結構淺析

  • BeanFactory結構圖
  • Spring容器啟動過程
  • Bean例項化過程

1、bean實現Aware介面的意義(圖中檢查Aware相關介面並設定相關依賴)

package com.anotation.bean;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class Dog implements ApplicationContextAware {

	private String name;

	//10公;20母
	private Integer sex;
	
	private ApplicationContext applicationContext;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getSex() {
		return sex;
	}

	public void setSex(Integer sex) {
		this.sex = sex;
	}

	public Dog(){
		System.out.println("dog constructor...");
	}
	
	//物件建立並賦值之後呼叫
	@PostConstruct
	public void init(){
		System.out.println("
[email protected]
"); } //容器移除物件之前呼叫 @PreDestroy public void detory(){ System.out.println("[email protected]"); } //實現ApplicationContextAware介面,並重寫他的setApplicationContext()方法,可以讓當前物件擁有容器的ApplicationContext引用 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", sex=" + sex + '}'; } }

2、實現BeanPostProcessor的作用:他的兩個方法都傳入了物件例項的引用,這為我們擴充套件容器的物件例項化過程中的行為提供了極大的便利,我們幾乎可以對傳入的物件例項做任何操作

package com.anotation.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 *
 * 建立一個BeanPost類,實現BeanPostProcessor介面。
 * 在其postProcessAfterInitialization()方法中修改通過引數傳入的受管Bean,然後返回。
 * 由於它處理容器中的每一個Bean,因此在修改前,應判斷Bean是否為我們要處理的Bean。
 * 可以通過傳入Bean的型別判定,也可以通過傳入Bean的名字判定
 *
 * @author zhengchao
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
        System.out.println("BeanPostProcessor.postProcessAfterInitialization 正在預處理!");
        //過濾特定型別的bean來修改bean的屬性或其為其進行增強(AOP就是基於此原理)
        if ((bean instanceof Dog)){
            Dog dog = (Dog) bean;
            dog.setName("范冰冰");
            dog.setSex(20);
            return bean;
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
        return bean;
    }
}

3、spring Aop手寫實現

public interface ITask {
    void execute();
}

public class TaskImpl implements ITask{
    @Override
    public void execute() {
        Date date = new Date();
        System.out.println("資訊:["+date+"] 呼叫了execute()方法。");
    }
}

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
import java.util.Date;
/**
 * 基於jdk的動態代理實現自己的aop: pointcut&&advice (還有一種cglib)
 */
public class MethodBeforeAdviceImpl implements MethodBeforeAdvice, AfterReturningAdvice {

    //攔截方法之前執行
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
        Date date = new Date();
        System.out.println("資訊:["+date+"] 呼叫了before()方法。");
    }

    //攔截方法返回結果之後執行
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
            throws Throwable {
        Date date = new Date();
        System.out.println("資訊:["+date+"] 呼叫了afterReturning()方法。");
    }
}

public class MainTest {

    public static void main(String[] args) {
        TaskImpl task = new TaskImpl();

        NameMatchMethodPointcut pc=new NameMatchMethodPointcut();
        pc.addMethodName("execute");

        Advice advice=new MethodBeforeAdviceImpl();
        Advisor advisor=new DefaultPointcutAdvisor(pc,advice);

        //建立BeanOne代理
        ProxyFactory pf1=new ProxyFactory();
        pf1.addAdvisor(advisor);
        pf1.setTarget(task);
        ITask proxyObject = (ITask)pf1.getProxy();
        proxyObject.execute();
    }
}

返回:
資訊:[Mon Oct 22 21:28:12 CST 2018] 呼叫了before()方法。
資訊:[Mon Oct 22 21:28:12 CST 2018] 呼叫了execute()方法。
資訊:[Mon Oct 22 21:28:12 CST 2018] 呼叫了afterReturning()方法。

to be continue

相關推薦

Spring原始碼解讀以及Spring整體結構淺析

BeanFactory結構圖 Spring容器啟動過程 Bean例項化過程 1、bean實現Aware介面的意義(圖中檢查Aware相關介面並設定相關依賴) package com.anotation.bean; import org.springframew

Spring原始碼解讀Spring MVC HandlerMapping元件(二)

一、HandlerMapping HandlerMapping作用是根據request找到相應的處理器Handler和Interceptors,並將Handler和Interceptors封裝成HandlerExecutionChain 物件返回。Handler

Spring原始碼解讀之核心容器上節

Spring架構圖 說明 Spring的流行程度就不用我來說了,相信大家如果使用JAVA開發就一定知道它。寫這篇文章的初衷在於:1.瞭解Spring底層實現原理,提升對Spring的認識與理解。2.學習優秀框架程式設計實現,學習優秀的設計模式。3.使用Spring三年多,對於底層細節希望知道更多,便於

Spring原始碼解讀之核心容器下節

續 上一篇我們通過ClassPathXmlApplicationContext載入xml檔案,通過BeanFactory獲取例項bean的demo程式碼去解讀了Spring Core Container中的spring-beans,spring-core,spring-context三個元件之間的一些具體類

Spring原始碼閱讀】 DefaultListableBeanFactory繼承結構講解分析

在基於ClassPathXmlApplicationContext建立BeanFactory時,我們從程式碼裡看到,建立的BeanFactory的型別是DefaultListableBeanFactory。 下面我們來分析下DefaultListableBeanFactory的繼承結構,

spring原始碼解讀:BeanFactory介面

不知道為什麼看著Spring的原始碼,感觸最深的是Spring對概念的抽象,所以我就先學介面了,BeanFactory是Spring IOC實現的基礎,這邊定義了一系列的介面,我們通過這些介面的學習,可以大致瞭解BeanFactory體系各介面如何分工合作。 為學習具體實現

Spring原始碼解讀與設計詳析 2018 (最全)

預設情況: 通常情況下子級div在浮動的情況下,會對父級的div後面的元素佈局產生影響,因為div在浮動的情況下,會脫離正常的文件流導致父級的盒子不能被撐起。這樣父級的高度就可能是0,會影響整個佈局。程式碼和效果如下: 程式碼: <style>     

Spring原始碼解讀之——bean的生命週期(隨筆)

bean建立---初始化----銷燬的過程 容器管理bean的生命週期; 我們可以自定義初始化和銷燬方法;容器在bean進行到當前生命週期的時候來呼叫我們自定義的初始化和銷燬方法 構造(物件建立)     單例項:在容器啟動的時候建立物件     多例項:在每次獲取的時

Spring原始碼解析筆記1——整體架構+配置檔案讀取

Spring整體架構 1.Core Container核心容器,包含Core,Beans,Context,Expression Language.Core和Beans提供最基本的IOC(控制反轉)和依賴注入。 Core模組主要包含Spring基本框架的核心

Spring原始碼解讀之——元件註冊(隨筆)

@ComponentScan  value:指定要掃描的包 excludeFilters = Filter[] :指定掃描的時候按照什麼規則排除那些元件 includeFilters = Filt

spring原始碼解讀之 JdbcTemplate原始碼

    在Spring中,JdbcTemplate是經常被使用的類來幫助使用者程式操作資料庫,在JdbcTemplate為使用者程式提供了許多便利的資料庫操作方法,比如查詢,更新等,而且在Spring中,有許多類似 JdbcTemplate的模板,比如HibernateT

Spring原始碼解讀之——自動裝配(隨筆)

Spring利用依賴注入(DI),完成對IOC容器中中各個元件的依賴關係賦值; 1、@Autowired:自動注入:     1)、預設優先按照型別去容器中找對應的元件:applicationContext.getBean(BookDao.class);找到就賦值   

XBMC原始碼分析 1:整體結構以及編譯方法

XBMC(全稱是XBOX Media Center)是一個開源的媒體中心軟體。XBMC最初為Xbox而開發,可以執行在Linux、OSX、Windows、Android4.0系統。我自己下載了一個然後體驗了一下,感覺確實不錯,和Windows自帶的媒體中心差不多。 XB

四、spring原始碼解讀初始化

 4.1、什麼是IOC/DI? IOC(Inversion of Control)控制反轉:所謂控制反轉,就是把原先我們程式碼裡面需要實現物件建立、依賴的程式碼,反轉給容器來幫忙實現。那麼必然的我們需要建立一個容器,同時需要一種描述來讓容器知道需要建立的物件與物件的關係。這描述最具體的

Spring原始碼學習之BeanFactory體系結構

public interface AutowireCapableBeanFactory extends BeanFactory { /** * Constant that indicates no externally defined autowiring. Note that

spring 原始碼解讀與設計詳解:6 BeanDefinitionParserDelegate與資源解析

上篇文章中提到了spring資源載入的核心程式碼為; DefaultBeanDefinitionDocumentReader類中的void registerBeanDefinitions(Document doc, XmlReaderContext readerContex

Spring原始碼解讀】BeanFactory和FactoryBean區別及類裝載原始碼解讀

最近讀程式碼讀到Bean裝載過程,順帶上網搜了下BeanFactory和FactoryBean,發現好多文章都講的不清不楚,特此自己來整理了一份BeanFactory和FactoryBean的區別及講下bean的裝載和讀取過程的原始碼.     首先來

spring 原始碼解讀Spring IOC原理

//建立Bean的例項物件 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { //檢查確認Bean是可例項化的 Cl

Spring原始碼解讀-Spring IoC容器初始化之資源定位

**IoC初始化過程 首先spring IoC容器的初始化,要分成三大部分,BeanDefinition的 Resource定位、載入和註冊三個基本過程。 今天我要說的就是資原始檔的定位,IoC容

spring 原始碼解讀與設計詳解:5 XmlBeanDefinitionReader與Resource

spring資源載入過程簡單說分三步: 1、定位資源,也就是找到配置檔案 2、載入檔案,將檔案解析為一個個元素和屬性 3、將bean物件註冊到ioc容器中,如果存在依賴注入,則根據配置檔案選擇是否在載入容器的時候將依賴注入載入,預設是true。 下面我們一步一步分析De