Java SpringBoot容器注入對象詳解
1.注入的方式
方式一:使用Import注解
增加一個類HelloCompent
package com.lx.component;
public class HelloCompent {
public void say() {
System.out.println("HelloCompent.say hello");
}
}
@SpringBootApplication
@Import(HelloCompent.class)
public class StartProgramNoWeb {
public static void main(String[] args) {
System.out.println("啟動");
SpringApplication.run(StartProgramNoWeb.class, args);
}
}
使用@Import就可以將HelloCompent注入到容器中。(HelloCompent類不需要增加@Service ,
@Component等注解)

方式二:使用@Service 或者@Component等注解注入到容器中
在需要注入的類增加注解,修改HelloCompent類
package com.lx.component;
import org.springframework.stereotype.Component;
@Component
public class HelloCompent {
public void say() {
System.out.println("HelloCompent.say hello");
}
}

方式三:使用@Configuration和@Bean組合實現(xiàn)
使用@Configuration和@Bean組合注入可以將對象注入到容器中,我主要生效的還是@Bean,如果將@Configuration換成@Component也是可以正常注入的。
增加一個CustomConfig類
package com.lx.config;
import com.lx.component.HelloCompent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomConfig {
@Bean("helloCompentConfig")
public HelloCompent helloCompent() {
return new HelloCompent();
}
}
這里我使用了方式2和3同時注入了,會導致重復注入而發(fā)生異常。所以我在bean是增加一個名稱,所以打印容器里對象的名稱也就是設置的名稱。

springboot自動配置注入對象就是使用的方式3實現(xiàn)注入對象到容器中,平時最常用的就是方式2和方式3,如果同時使用方式2和方式3注入會出現(xiàn)注入重復的對象。
2.注入是增加條件判斷注解
@ComponentScan:聲明作用域
@ConditionalOnBean:當容器里有指定Bean的條件下
@ConditionalOnClass:當類路徑下有指定的類的條件下
@ConditionalOnExpression:基于SpEL表達式為true的時候作為判斷條件才去實例化
@ConditionalOnJava:基于JVM版本作為判斷條件
@ConditionalOnJndi:在JNDI存在的條件下查找指定的位置
@ConditionalOnMissingBean:當容器里沒有指定Bean的情況下
@ConditionalOnMissingClass:當容器里沒有指定類的情況下
@ConditionalOnWebApplication:當前項目時Web項目的條件下
@ConditionalOnNotWebApplication:當前項目不是Web項目的條件下
@ConditionalOnProperty:指定的屬性是否有指定的值
@ConditionalOnProperty(prefix = "customconfig",name = "enable",havingValue = "true") 等效于@ConditionalOnProperty(value = "customconfig.enable",havingValue = "true")
@ConditionalOnResource:類路徑是否有指定的值
@ConditionalOnOnSingleCandidate:當指定Bean在容器中只有一個,或者有多個但是指定首選的Bean
這些注解都組合了@Conditional注解,只是使用了不同的條件組合最后為true時才會去實例化需要實例化的類,否則忽略
3.構造方法時帶參數(shù)注入
有時候在實際工作中,我們需要在構造方法是增加一些處理邏輯,同事也需要從容器中獲取對象,但是這時候我們在構造方式時想從容器中獲取對象,實際上并不能獲取到。因為這個spring的注解優(yōu)先級有關系。當構造方法使用字段時,spring并沒有將對象注入成功,所有構造方式取值也就是用。
package com.lx.component;
import com.lx.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class HelloTwoCompent {
@Value("${proper.name}")
private String name;
@Autowired
private HelloService helloService;
public HelloTwoCompent() {
System.out.println("hellotwo 無參");
System.out.println("name=" + name + ";helloService=" + helloService);
if (helloService != null) {
helloService.print();
}
}
}

方式1:使用spring xml實現(xiàn)
新增加一個用于測試的類HelloTwoCompent
在xml bean節(jié)點上增加構造方法參數(shù)配置即可。然后在springboot啟動類上增加@ImportResource(locations= {"classpath:application-bean.xml"})。這里我不喜歡用,暫時就不寫測試代碼了。
方式2:使用@Autowired
修改HelloTwoCompent 類在構造方法上增加@Autowired
@Autowired
public HelloTwoCompent( @Value("${proper.name}") String name, HelloService helloService) {
System.out.println("hellotwo 兩參");
System.out.println("name=" + name + ";helloService=" + helloService);
if (helloService != null) {
helloService.print();
}
}

方式3使用@Configuration和@Bean組合
增加一個配置了 HelloConfig
package com.lx.config;
import com.lx.component.HelloTwoCompent;
import com.lx.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HelloConfig {
@Value("${proper.name}")
private String name;
@Autowired
private HelloService helloService;
@Bean("helloTwoCompentBean")
public HelloTwoCompent helloTwoCompent() {
return new HelloTwoCompent(name,helloService,"config-bean");
}
}
修改一下HelloTwoCompent,增加一個三個參數(shù)的構造方法,并且構造方法上不增加任何的注解。
public HelloTwoCompent(String name, HelloService helloService,String type) {
System.out.println("hellotwo 三參;type="+type);
System.out.println("name=" + name + ";helloService=" + helloService);
if (helloService != null) {
helloService.print();
}
}

4.對象注入時的一些總結
1.靜態(tài)字段不支持@Autowired和@Resource實現(xiàn)自動裝配,因為自動裝配依賴于set和get方法,@Autowired和@Resource就是消除set和get方法。
2.自動裝配的字段可以為private,因為自動裝配依賴于set和get方法。所以和字段的作用域無關。
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
Spring?Boot?快速使用?HikariCP?連接池配置詳解
Spring Boot 2.x 將其作為默認的連接池組件,項目中添加 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 模塊后,HikariCP 依賴會被自動引入,這篇文章主要介紹了Spring?Boot使用HikariCP連接池配置詳解,需要的朋友可以參考下2023-06-06
Spring6?的JdbcTemplate的JDBC模板類的使用介紹(最新推薦)
JdbcTemplate?是Spring?提供的一個JDBC模板類,是對JDBC的封裝,簡化JDBC代碼,當然,你也可以不用,可以讓Spring集成其它的ORM框架,這篇文章主要介紹了Spring6?的JdbcTemplate的JDBC模板類的詳細使用說明,需要的朋友可以參考下2024-05-05
SpringBoot項目打包成jar后獲取classpath下文件失敗的解決
這篇文章主要介紹了SpringBoot項目打包成jar后獲取classpath下文件失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Java Redis Template批量查詢指定鍵值對的實現(xiàn)
本文主要介紹了Java Redis Template批量查詢指定鍵值對的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07

