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

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring Boot2.x-04Spring Boot基础-使用注解装配bean

發(fā)布時(shí)間:2025/3/21 javascript 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot2.x-04Spring Boot基础-使用注解装配bean 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 概述
  • 通過Java配置文件@Bean的方式定義Bean
  • 通過注解掃描的方式(@Component/@ComponentScan)裝配Bean
    • 使用excludeFilters屬性不讓IoC加載某些Bean
  • 裝配第三方 Bean

概述

Spring Boot主要是通過注解來裝配 Bean 到 Spring IoC 容器中,使用注解裝配Bean就不得不提AnnotationConfigApplicationContext,很顯然它是一個(gè)基于注解的 IoC 容器。

之前的博文 Spring-基于Java類的配置


通過Java配置文件@Bean的方式定義Bean

POJO類

package com.artisan.springbootmaster.pojo;public class Artisan {public String name;public int age;// setter/getter }

然后編寫一個(gè)配置文件

package com.artisan.springbootmaster;import com.artisan.springbootmaster.pojo.Artisan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class AppConfig {@Bean(name = "artisan")public Artisan initArtisan(){Artisan artisan = new Artisan();artisan.setName("小工匠");artisan.setAge(20);return artisan;} }
  • @Configuration 代表是一個(gè) Java 配置文件 , Spring會(huì)根據(jù)它來生成 IoC 容器去裝配 Bean
  • @Bean 代表將 initArtisan方法返回的 POJO 裝配到 IoC 容器中,屬性 name 定義 Bean 的名稱,如果沒有配置它,則會(huì)將方法名稱“initArtisan作為 Bean 的名稱保存到 Spring IoC 容器中 。

使用 AnnotationConfigApplicationContext 來構(gòu)建

package com.artisan.springbootmaster;import com.artisan.springbootmaster.pojo.Artisan; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class LoadTest {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);//Artisan artisan = applicationContext.getBean(Artisan.class);Artisan artisan = (Artisan) applicationContext.getBean("artisan");System.out.println(artisan.getName() + " || " + artisan.getAge());} }
  • new AnnotationConfigApplicationContext(AppConfig.class) 將 Java 配置文件 AppConfig 傳遞給 AnnotationConfigApplicationContext 的構(gòu)造方法,這樣它就能夠?qū)嵗撆渲妙愔卸x的信息,然后將配置里面的 Bean 裝配到 IoC 容器中
  • 裝載到IoC容器以后,就可以使用getBean來獲取對(duì)應(yīng)實(shí)例化的bean信息了

輸出 :

23:08:36.164 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'artisan' 小工匠 || 20

關(guān)鍵日志:Returning cached instance of singleton bean 'artisan' ,可以知道配置在配置文件中 的名稱為 artisan的 Bean 已經(jīng)被裝配到 IoC 容器中 ,并且可以通過 getBean方法獲取對(duì)應(yīng)的 Bean.


通過注解掃描的方式(@Component/@ComponentScan)裝配Bean

Spring 中可以使用 XML 或者 Java 配置文件的方式裝配 Bean , 但是由于 Spring Boot 是基于注解的方式,因此我們來說下基于注解的方式.

上面的例子使用Java配置文件的方式,使注解@Bean 注入 Spring loC 容器中,假設(shè)有多個(gè)bean的話,就需要多個(gè)@Bean來標(biāo)注多次。

Spring也提供通過掃描的方式去裝配bean到IoC容器中。 對(duì)于掃描裝配而言使用的注解是@Component和@ComponentScan.

  • @Component:標(biāo)明哪個(gè)類被掃描進(jìn)入 Spring IoC 容器
  • @ComponentScan:標(biāo)明采用何種策略去掃描裝配 Bean

同樣的,我們還是用上個(gè)例子來演示下用法

我們先假設(shè)AppConfig1.java 和 Artisan.java在同一個(gè)包下面 ,

然后對(duì)Artisan這個(gè)類加上@Component注解,如下

package com.artisan.springbootmaster.pojo;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;@Component("artisan") public class Artisan {@Value("little_artisan")public String name;@Value("99")public int age;// setter/getter}
  • 注解@Component 表明這個(gè)類將被Spring IoC容器掃描裝配,bean的名稱為artisan。 如果不配置這個(gè)值 ,那IoC 容器就會(huì)把類名第一個(gè)字母作為小寫,其他的不變作為 Bean 名稱放入到 IoC 容器中。

  • 注解@Value 則是指定具體的值,使得 Spring IoC 給予對(duì)應(yīng)的屬性注入對(duì)應(yīng)的值

為了讓 Spring IoC 容器裝配這個(gè)類 , 我們來改造下AppConfig,重新命名為AppConfig1,加入注解@ComponentScan,并取消掉其中的@Bean的配置。

package com.artisan.springbootmaster.pojo;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan public class AppConfig1 {}

加入了@ComponentScan,意味著它會(huì)進(jìn)行掃描,但是只是個(gè)干巴巴的注解,什么屬性都沒設(shè)置,這就意味著它只會(huì)掃描類 AppConfig1 所在的當(dāng)前包和其子包。 因?yàn)锳rtisan和它在同一個(gè)目錄下,所以可以刪掉之前使用@Bean 標(biāo)注的創(chuàng)建對(duì)象方法。

測(cè)試同第一個(gè)例子

package com.artisan.springbootmaster;import com.artisan.springbootmaster.pojo.AppConfig1; import com.artisan.springbootmaster.pojo.Artisan; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class LoadTest2 {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig1.class);Artisan artisan = applicationContext.getBean(Artisan.class);System.out.println(artisan.getName() + " || " + artisan.getAge());}

23:17:05.981 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'artisan' little_artisan || 99

來,繼續(xù)優(yōu)化,上面為了讓Spring掃描到Artisan, 把Artisan.java類和AppConfig1.java放在一塊,實(shí)在是不合理。所以:使用 @ComponentScan自定義掃包

那就去看下@ComponentScan源碼吧

定義:

@Repeatable(ComponentScans.class) 是說可重復(fù)定義,可定義多個(gè)。

方法:

說幾個(gè)比較常用的

  • basePackages: 定義掃描的包名,在沒有定義的情況下,只會(huì)掃描當(dāng)前包和其子包下的路徑。
  • includeFilters :定義滿足過濾器( Filter )條件的 Bean 才去 掃描,
  • excludeFilters :排除過濾器條件的 Bean , 和includeFilters 一樣都需要通過注解@Filter 去定義,@Filter中的type 類型,可以定義為注解或者正則式等類型
  • @Filter中classes屬性定義注解類, pattern屬性 定義正則式類。

來吧,把Artisan還是放在pojo下,AppConfig1.java換個(gè)地方吧 ,并通過以下任意方式指定使得 IoC 容器去掃描到 User 類即可

package com.artisan.springbootmaster;import com.artisan.springbootmaster.pojo.Artisan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration //@ComponentScan(basePackages = "com.artisan.springbootmaster.*") @ComponentScan(basePackages = "com.artisan.springbootmaster.pojo") //@ComponentScan(basePackageClasses = Artisan.class) public class AppConfig1 {}

運(yùn)行測(cè)試,結(jié)果同樣可以獲取到


使用excludeFilters屬性不讓IoC加載某些Bean

假設(shè)AppConfig1上配置的basePackages 屬性為basePackages = "com.artisan.springbootmaster.*", 在springbootmaster目錄下還有個(gè)service包,里面的類都標(biāo)注了@Service注解,假設(shè)我們只想讓IoC容器掃描到Artisan類,而不掃描ArtisanService類呢?

只需要加上excludeFilters屬性,通過excludeFilters 指定排除掉標(biāo)注了Service注解的類即可

package com.artisan.springbootmaster;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Service;@Configuration @ComponentScan(basePackages = "com.artisan.springbootmaster.*",excludeFilters = {@ComponentScan.Filter(classes = {Service.class})}) public class AppConfig1 {}

驗(yàn)證下吧

package com.artisan.springbootmaster;import com.artisan.springbootmaster.pojo.Artisan; import com.artisan.springbootmaster.service.ArtisanService; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class LoadTest2 {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig1.class);Artisan artisan = applicationContext.getBean(Artisan.class);System.out.println(artisan.getName() + " || " + artisan.getAge());ArtisanService artisanService = applicationContext.getBean(ArtisanService.class);artisanService.doSomething();} } 23:54:04.274 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'artisan' little_artisan || 99 Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.artisan.springbootmaster.service.ArtisanService' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:346)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:333)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)at com.artisan.springbootmaster.LoadTest2.main(LoadTest2.java:16)Process finished with exit code 1

可以看到,No qualifying bean of type 'com.artisan.springbootmaster.service.ArtisanService' available,Spring IoC容器并沒有在啟動(dòng)的時(shí)候去掃表標(biāo)注了@Service的ArtisanService類,說明excludeFilters 起了作用 。由于加入了 excludeFilters 的配置,使標(biāo)注了@Service 的類將不被 IoC 容器掃描注入


裝配第三方 Bean

一個(gè)項(xiàng)目中,不可避免的要使用到第三方的jar,如果希望把第三方包的類對(duì)象也放入到 Spring IoC 容器中,@Bean 注解就發(fā)揮用處了。

如下

package com.artisan.redpacket.config;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp2.BasicDataSourceFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.TransactionManagementConfigurer;@Configuration //定義Spring 掃描的包 @ComponentScan(value= "com.*", includeFilters= {@Filter(type = FilterType.ANNOTATION, value ={Service.class})}) //使用事務(wù)驅(qū)動(dòng)管理器 @EnableTransactionManagement //實(shí)現(xiàn)接口TransactionManagementConfigurer,這樣可以配置注解驅(qū)動(dòng)事務(wù) public class RootConfig implements TransactionManagementConfigurer {private DataSource dataSource = null;/*** 配置數(shù)據(jù)庫.* @return 數(shù)據(jù)連接池*/@Bean(name = "dataSource")public DataSource initDataSource() {if (dataSource != null) {return dataSource;}try {Properties props = new Properties();props.load(RootConfig.class.getClassLoader().getResourceAsStream("jdbc.properties"));props.setProperty("driverClassName", props.getProperty("jdbc.driver"));props.setProperty("url", props.getProperty("jdbc.url"));props.setProperty("username", props.getProperty("jdbc.username"));props.setProperty("password", props.getProperty("jdbc.password"));dataSource = BasicDataSourceFactory.createDataSource(props);} catch (Exception e) {e.printStackTrace();}return dataSource;}/**** 配置SqlSessionFactoryBean* @return SqlSessionFactoryBean*/@Bean(name="sqlSessionFactory")public SqlSessionFactoryBean initSqlSessionFactory() {SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();sqlSessionFactory.setDataSource(initDataSource());//配置MyBatis配置文件Resource resource = new ClassPathResource("mybatis/mybatis-config.xml");sqlSessionFactory.setConfigLocation(resource);return sqlSessionFactory;}/**** 通過自動(dòng)掃描,發(fā)現(xiàn)MyBatis Mapper接口* @return Mapper掃描器*/@Bean public MapperScannerConfigurer initMapperScannerConfigurer() {MapperScannerConfigurer msc = new MapperScannerConfigurer();msc.setBasePackage("com.*");msc.setSqlSessionFactoryBeanName("sqlSessionFactory");msc.setAnnotationClass(Repository.class);return msc;}/*** 實(shí)現(xiàn)接口方法,注冊(cè)注解事務(wù),當(dāng)@Transactional 使用的時(shí)候產(chǎn)生數(shù)據(jù)庫事務(wù) */@Override@Bean(name="annotationDrivenTransactionManager")public PlatformTransactionManager annotationDrivenTransactionManager() {DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(initDataSource());return transactionManager;}}

上面通過@Bean 如果指定了name屬性的名字,Spring 就會(huì)把該name的值作為bean的名稱 保存在 loC 容器中如果不填name的值,Spring就會(huì)用方法名作為 Bean 名稱保存到IoC 容器中。


總結(jié)

以上是生活随笔為你收集整理的Spring Boot2.x-04Spring Boot基础-使用注解装配bean的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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