日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring5源码 - Spring IOC 注解复习

發(fā)布時間:2025/3/21 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring5源码 - Spring IOC 注解复习 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • Pre
  • xml配置文件
  • JavaConfig
  • @CompentScan
    • 在配置類上寫@CompentScan注解來進行包掃描
    • excludeFilters
    • includeFilters
    • @ComponentScan.Filter type的類型
      • 使用自定義過濾器CUSTOM
  • @Scope
  • @Lazy
  • @Conditional 條件判斷


Pre

為了更好地學(xué)習(xí)源碼,我們有必要對基礎(chǔ)知識進行一次簡單的復(fù)習(xí),只有在知道如何使用的基礎(chǔ)上,再去閱讀源碼才能明白spring這些源碼是對哪些功能的支持。

這里簡單的梳理一下


xml配置文件

【配置文件 】

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="artisan" class="com.artisan.base.Artisan"/> </beans>

【讀取Bean】

ClassPathXmlApplicationContext cx = new ClassPathXmlApplicationContext("classpath:spring.xml"); System.out.println(cx.getBean("artisan").getClass().getSimpleName());}

【輸出】


JavaConfig

【POJO】

public class Bean1 { }

【配置文件 】

@Configuration public class MainConfig {@Beanpublic Bean1 bean1(){return new Bean1();} }

【讀取Bean— 傳入配置類】

public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);System.out.println(ac.getBean("bean1"));}

@Bean的形式, bean的默認名稱是方法名,若@Bean(value=“bean的名稱”) ,那么bean的名稱是指定的名稱。

【測試結(jié)果】


@CompentScan

在配置類上寫@CompentScan注解來進行包掃描

【配置類】

package com.artisan.base.componentscan.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.artisan.base.componentscan") public class CSMainConfig {}

【c - s -d 】

package com.artisan.base.componentscan.controller;import org.springframework.stereotype.Controller;@Controller public class ArtisanInfoController { } package com.artisan.base.componentscan.service;import org.springframework.stereotype.Service;@Service public class ArtisanService { } package com.artisan.base.componentscan.dao;import org.springframework.stereotype.Repository;@Repository public class ArtisanDao { }

【測試類】

package com.artisan.base.componentscan;import com.artisan.base.componentscan.config.CSMainConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class CMTest {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(CSMainConfig.class);// 輸出 單例池中的單例bean的名字for (String beanDefinitionName : ac.getBeanDefinitionNames()) {System.out.println("bdName:" + beanDefinitionName);}} }

【輸出】


excludeFilters

【配置類】

import com.artisan.base.componentscan.service.ArtisanService; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller;@Configuration @ComponentScan(basePackages = {"com.artisan.base.componentscan"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {ArtisanService.class}) }) public class CSMainConfig {}

重點配置

@ComponentScan(basePackages = {"com.artisan.base.componentscan"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {ArtisanService.class}) })

excludeFilters(排除@Controller注解的,和ArtisanService的)

【測試結(jié)果】


includeFilters

@Configuration @ComponentScan(basePackages = {"com.artisan.base.componentscan"},includeFilters ={@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class})},useDefaultFilters = false)public class CSMainConfig {}

若使用包含的用法, 需要把useDefaultFilters屬性設(shè)置為false(true表示掃描全部的)

【測試結(jié)果】


@ComponentScan.Filter type的類型

看下源碼

public enum FilterType {/*** Filter candidates marked with a given annotation.* @see org.springframework.core.type.filter.AnnotationTypeFilter*/ANNOTATION,/*** Filter candidates assignable to a given type.* @see org.springframework.core.type.filter.AssignableTypeFilter*/ASSIGNABLE_TYPE,/*** Filter candidates matching a given AspectJ type pattern expression.* @see org.springframework.core.type.filter.AspectJTypeFilter*/ASPECTJ,/*** Filter candidates matching a given regex pattern.* @see org.springframework.core.type.filter.RegexPatternTypeFilter*/REGEX,/** Filter candidates using a given custom* {@link org.springframework.core.type.filter.TypeFilter} implementation.*/CUSTOM}
  • ANNOTATION 注解形式 舉個例子比如 @Compent @Controller @Service @Repository .......
  • ASSIGNABLE_TYPE 指定類型的 FilterType.ASSIGNABLE_TYPE 舉個例子
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {ArtisanService.class})
  • ASPECTJ 類型的 FilterType.ASPECTJ 不常用
  • REGEX 正則表達式的 FilterType.REGEX 不常用
  • CUSTOM 自定義類型

使用自定義過濾器CUSTOM

package com.artisan.base.componentscan.customFilterType;import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter;import java.io.IOException;public class ArtisanFilterType implements TypeFilter {@Overridezpublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//獲取當(dāng)前類的注解源信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//獲取當(dāng)前類的class的源信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//獲取當(dāng)前類的資源信息Resource resource = metadataReader.getResource();System.out.println("類的路徑:"+classMetadata.getClassName());// 排除包含Artisan的Beanif(classMetadata.getClassName().contains("Artisan")) {return true;}return false;} }

【配置類】

@Configuration @ComponentScan(basePackages = {"com.artisan.base.componentscan"},excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, value = {ArtisanFilterType.class})}) public class CSMainConfig {}

【測試結(jié)果】


@Scope

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes


public class Bean2 {public Bean2() {System.out.println("Bean2 Created");} } public class Bean3 {public Bean3() {System.out.println("Bean3 Created");} }

【config】

package com.artisan.base.scope;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope;@Configuration public class Config {@Bean()public Bean2 bean2(){return new Bean2();}@Bean()@Scope(value = "prototype")public Bean3 bean3(){return new Bean3();}}

【測試bean的加載】

package com.artisan.base.scope;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class TestScope {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);System.out.println("========================");// 每次調(diào)用都會實例化一個新的Bean3+System.out.println(ac.getBean("bean3"));System.out.println(ac.getBean("bean3"));} }

【輸出】


【結(jié)論】

  • 在不指定@Scope的情況下,所有的bean都是單實例的bean,而且是餓漢加載 即 容器啟動實例就創(chuàng)建好了

  • 指定@Scope為 prototype 表示為原型bean,而且還是懶漢模式加載 , 即IOC容器啟動的時候,并不會創(chuàng)建對象,而是 在第一次使用的時候才會創(chuàng)建 ,并且每次調(diào)用,都會實例化一個新的對象


@Lazy

Bean的懶加載@Lazy 主要針對單實例的bean 容器啟動的時候,不創(chuàng)建對象,在第一次使用的時候才會創(chuàng)建該對象 ,后續(xù)調(diào)用不會新建對象,而是從單例池中獲取緩存的bean。

繼續(xù)使用上面的例子 ,給Bean2 加上Lazy注解

@Bean()@Lazypublic Bean2 bean2(){return new Bean2();}

【測試】

import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class TestScope {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);System.out.println(ac.getBean("bean2"));System.out.println(ac.getBean("bean2"));} }

【結(jié)果】


@Conditional 條件判斷

需求: 只有容器中有bean5 才裝載bean6


value 是一個class數(shù)組, 需要實現(xiàn)Condition 接口 , 那我們也弄個唄

【自定義Condition 】

package com.artisan.base.condition;import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata;public class ArtisanCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//判斷容器中是否有Bean5 ,有的話 返回trueif(context.getBeanFactory().containsBean("bean5")) {return true;}return false;} }

【config 】

package com.artisan.base.condition;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration;@Configuration public class CDConfig {@Beanpublic Bean5 bean5(){return new Bean5();}// Conditional的條件返回true,才裝載Bean6@Bean@Conditional(value = ArtisanCondition.class)public Bean6 bean6(){return new Bean6();}}

【beans】

public class Bean5 {public Bean5() {System.out.println("Bean5 Created");} } public class Bean6 {public Bean6() {System.out.println("Bean6 Created");} }

【正常情況】

package com.artisan.base.condition;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class CDTest {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(CDConfig.class);for (String beanDefinitionName : ac.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}} }

我們看到了 CDConfig中 bean5 上標(biāo)注了@Bean

現(xiàn)在我們把Bean5的@Bean去掉

總結(jié)

以上是生活随笔為你收集整理的Spring5源码 - Spring IOC 注解复习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。