最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

寫了兩年代碼之后再來談一談Spring中的Bean

 更新時(shí)間:2021年10月12日 09:36:39   作者:Java魚仔  
這篇文章主要介紹了寫了兩年代碼之后再來看看Spring中的Bean,這里列出四種常用的添加Bean的方式,介紹最基本的@Bean注解,@Bean注解聲明這個(gè)類是一個(gè)Bean,需要的朋友可以參考下

(一)什么是Bean

Spring中的Bean簡單來講就是一個(gè)個(gè)被Spring容器管理的Java對(duì)象,我們寫了一個(gè)類之后,這個(gè)類只是一個(gè)單純的Java類,可以通過new的方式去創(chuàng)建它。當(dāng)我們把這個(gè)類添加到Spring的容器里之后,這個(gè)類就變成了Bean,由Spring容器管理,可以通過自動(dòng)注入的方式去使用。

(二)如何往Spring容器中添加Bean

這里列出四種常用的添加Bean的方式。

1、@Bean: 寫一個(gè)普通的類時(shí)最常用的添加Bean的方式

2、@ComponentScan + @Controller @Service @Component @Repository:SpringBoot寫多了之后一定會(huì)很熟悉這些。

3、@Import:通過導(dǎo)入的方式注入Bean

4、@ImportBeanDefinitionRegister:和Import類似,可以指定Bean的名稱

(三)Bean的作用域

首先介紹最基本的@Bean注解,@Bean注解聲明這個(gè)類是一個(gè)Bean,在Spring5之前,大部分的聲明都會(huì)放到配置文件里,Spring5之后通過兩個(gè)注解就可以完成。以Teacher類為例

public class Teacher {
}

@Configuration
public class MainConfig {
    @Bean
    public Teacher teacher(){
        return new Teacher();
    }
}

在不指定@Scope的情況下,所有bean的實(shí)例都是單實(shí)例的bean,并且是餓漢式加載(容器啟動(dòng)時(shí)就創(chuàng)建好了)??梢酝ㄟ^注解@Lazy實(shí)現(xiàn)懶加載(在調(diào)用時(shí)被加載)。

@Bean
//@Lazy
public User user(){
    return new User();
}

指定@Scope為prototype表示為多實(shí)例,并且是懶漢式加載(使用時(shí)才會(huì)創(chuàng)建)

@Bean
@Scope(value = "prototype")
public User user(){
    return new User();
}

列出其他的幾種Bean作用域:

singleton  單例(默認(rèn))
prototype  多實(shí)例
request  同一次請(qǐng)求
session  同一個(gè)會(huì)話級(jí)別

(四)Bean的常用注解

有幾個(gè)注解經(jīng)常會(huì)和@Bean一起使用

4.1 Conditional

Conditional注解的意思是條件,即滿足條件的情況下才會(huì)生效
比如我在Bean中配置了Conditional:

@Bean
@Conditional(value = TeacherCondition.class)
public Teacher teacher(){
    return new Teacher();
}

TeacherCondition 代碼如下:如果Spring的Bean中有名字為student的,則返回true,否則返回false

public class TeacherCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        if (conditionContext.getBeanFactory().containsBean("student")){
            return true;
        }
        return false;
    }
}

最后的結(jié)果就是,如果TeacherCondition返回的是true,則teacher這個(gè)bean會(huì)被注冊(cè)到容器中,否則就不會(huì)注冊(cè)到容器中。

4.2 ComponentScan

這個(gè)注解會(huì)和Controller、Service等同時(shí)出現(xiàn),給一個(gè)類添加Controller、Service等注解后,需要在配置類中增加ComponentScan,ComponentScan掃描到的包下的Controller、Service等注解才會(huì)生效:

@Configuration
//最基本的掃描路徑方式
//@ComponentScan(basePackages = {"com.javayz.testcompentscan"})
//增加了Filter的方式
@ComponentScan(basePackages = {"com.javayz.testcompentscan"},includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class, Service.class}),
        @ComponentScan.Filter(type = FilterType.CUSTOM,value = {TestFilterType.class})
},useDefaultFilters = false)
public class MainConfig {

    @Bean
    @Scope(value = "prototype")
    public User user(){
        return new User();
    }
}

Filter是在掃描時(shí)的過濾器,比如設(shè)置FilterType.ANNOTATION表示只有這里設(shè)置的注解才會(huì)被掃描到,F(xiàn)ilterType.CUSTOM是自定義過濾器,TestFilterType 類進(jìn)行了一層判斷:包名為dao下的類會(huì)被注冊(cè)到Bean容器中

public class TestFilterType implements TypeFilter {
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //獲取當(dāng)前類的class源信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        if (classMetadata.getClassName().contains("dao")){
            return true;
        }
        return false;
    }
}

4.3 @Import

@Import可以用來往容器中導(dǎo)入第三方的組件,也可以起到和@Bean一樣的作用:

@Configuration
//@Import(value = {Teacher.class, Student.class})
//@Import(value = {MyImportSelector.class})
@Import(value = {MyBeanDefinitionRegister.class})
public class MainConfig {
}

第一種方式直接導(dǎo)入對(duì)應(yīng)的類,這里和直接寫@Bean效果一致

@Import(value = {Teacher.class, Student.class})

第二種方式導(dǎo)入ImportSelector對(duì)象,通過selectImports方法返回要導(dǎo)入Bean的全限定名:

public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.javayz.testimport.compent.Teacher"};
    }
}

第三種方式通過BeanDefinitionRegister注入Bean(可以指定Bean的名稱)

public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Student.class);
        registry.registerBeanDefinition("student",rootBeanDefinition);
    }
}

Import注解最常用的場景就是SpringBoot自動(dòng)注入,在SpringBoot自動(dòng)注入源碼中導(dǎo)出可以看到@Import注解的身影。

(五)Bean的初始化和銷毀

當(dāng)由容器管理Bean的生命周期時(shí),我們可以通過自己指定Bean方法的初始化方法和銷毀方法,使得一個(gè)Bean在初始化和銷毀時(shí)能執(zhí)行自己的方法。

1、自定義初始化方法和銷毀方法

public class Teacher {
    public Teacher(){
        System.out.println("Teacher 構(gòu)造方法");
    }
    public void init(){
        System.out.println("Teacher 初始化方法");
    }
    public void destory(){
        System.out.println("Teacher 銷毀方法");
    }
}

@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Teacher teacher(){
        return new Teacher();
    }
}

對(duì)于單例bean(singleton)容器啟動(dòng)的時(shí)候,bean對(duì)象就創(chuàng)建了,在容器銷毀的時(shí)候,就會(huì)去調(diào)用Bean的銷毀方法。

對(duì)于多實(shí)例的bean,容器啟動(dòng)的時(shí)候bean還未被創(chuàng)建,在獲取Bean的時(shí)候才會(huì)被創(chuàng)建,并且bean的銷毀不受IOC容器的管理。

2、通過 InitializingBean, DisposableBean 接口實(shí)現(xiàn)

Spring的這兩個(gè)接口也可以實(shí)現(xiàn)初始化和銷毀的功能。

public class Student implements InitializingBean, DisposableBean {
    public Student(){
        System.out.println("Student 構(gòu)造方法");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("Student銷毀");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Student初始化");
    }
}
@Configuration
public class MainConfig {
    @Bean
    public Student student(){
        return new Student();
    }
}

3、BeanPostProcessor

BeanPostProcessor在所有Bean的初始化前和初始化后都會(huì)被調(diào)用

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean初始化前");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean初始化后");
        return bean;
    }
}

@ComponentScan
@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Teacher teacher(){
        return new Teacher();
    }
    @Bean
    public Student student(){
        return new Student();
    }
}

(六)總結(jié)

別看Bean這個(gè)概念聽起來簡單,里面的內(nèi)容還真不少。Spring的核心之一IOC也就是對(duì)Bean進(jìn)行管理。我是魚仔,我們下期再見!

到此這篇關(guān)于寫了兩年代碼之后再來看看Spring中的Bean的文章就介紹到這了,更多相關(guān)Spring中的Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

青岛市| 龙陵县| 宁晋县| 宁波市| 南阳市| 西畴县| 酒泉市| 富平县| 阿拉尔市| 林甸县| 防城港市| 吉首市| 富裕县| 延吉市| 丰原市| 东辽县| 湟源县| 涟源市| 乌鲁木齐县| 上饶市| 肥乡县| 呈贡县| 肥西县| 墨脱县| 高平市| 延川县| 鄢陵县| 连山| 黄冈市| 营口市| 宜章县| 泉州市| 富宁县| 尖扎县| 合作市| 成武县| 平陆县| 临安市| 增城市| 酒泉市| 武乡县|