本篇博客主要參考了【路人甲Java】系列博文的《Spring高手系列》的學習指導思路,進行的編碼和測試。
本文最後更新於:2022年03月06日
1. 引言
Srping時bean的管理容器。批量註冊bean是Spring的基本操作。
Spring批量註冊bean的方式有2種:
- @ComponentScan和@ComponentScans
- @Import
2. @ComponentScan(s)批量註冊
2.1 @ComponentScan
@ComponentScan用於批量註冊bean。該註解會讓spring去掃描【某些包以及其子包內的所有的類】,然後【將滿足一定條件的類作爲bean】註冊到容器中。
從這句話可以看出幾個重點:
- @ComponentScan掃描的是包,子包裏面的所有類。這就需要確認掃描哪些包。確認包的方式有兩種:
- 按照包名。也就是指定直接確認包名。
- 按照類名。也就是通過類名來間接確認包名。
- 將滿足一定調節的類作爲bean註冊到容器。這就需要通過某些調節來確認目標bean:
- useDefaultFilters默認過濾。有某些註解的類,可以作爲bean註冊。比如:@Component,@Controller,@Service,@Repository
- includeFilters白名單過濾。
- excludeFilters黑名單過濾。
@ComponentScan可以通過value或者basePackage來配置要掃描的包。通過value掃描時,使用方法如下:
@ComponentScan({"package01","package02"})
這樣就可以把package01和package02包內的類註冊爲bean。
注意:通過這樣指定包名掃描,有一個隱患:若包被重命名了,會導致掃描失效。
所以一般情況下,我們使用basePackageClasses的方式來指定掃描的包,該參數可以指定一些類型,默認會掃描這些類所在的包及其子包中所有的類,這種方式可以有效避免這種問題。
2.2 @includeFilters
2.2.1 掃描包含註解的類
如上所述,該註解通過一個Filter類型的數組,存放要被掃描的類。它作爲@CompoentScan的一個參數使用。
使用方法如下:
@ComponentScan(
useDefaultFilters = false; //默認是true
includeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION,classes=自定義註解)
}
)
通過includeFilters可以註冊自定義註解。但是這種自定義註解無法指定bean的名稱。
通過對自定義註解的改造,可以完成自定義bean能夠指定bean的名稱。
2.2.2 包含指定類型的類
使用方法如下:
@ComponentScan(
useDefaultFilters = false; //默認是true
includeFilters = {
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes=自定義類型.class)
}
)
這樣,被掃描的滿足【自定義類型.class.isAssignableFrom】條件的都會被註冊
2.3 自定義Filter
2.3 練習代碼
源碼目錄:/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev
- Person.Java 接口
- PersonImpl.java 實現類
- School.java 接口
- SchoolImpl.java 實現類
- SpringConfig.java 配置類
測試目錄:/root/liwldev/java/web/springframe/SpringAnnotation/src/test/java/com/liwl/dev
- MyTest.java
其他:
- 刪除bean.xml,完全使用註解來配置
- 保留all.properties外部屬性配置文件
2.3.1 @ComponentScan註解和@Component註解
這小節練習@Component註解。
使用該註解的類都會註冊到spring裏面,bean的名稱需要通過@Component(value = "bean名稱")來指定。如果不指定,則是以【首字母小寫的類名】作爲bean的名稱。
PersonImpl.java
package com.liwl.dev;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@PropertySource(value = {"classpath:all.properties"},encoding = "utf-8")
@Component
public class PersonImpl implements Person {
@Value(value = "${liwl_name}")
private String name;
@Value(value = "${liwl_age}")
private int age;
@Autowired
private School school; //這裏沒有使用@Qualifier註解
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
@Override
public String toString() {
return "PersonImpl->" + "name:" + name + ",age:" + age + ",school:" + school;
}
}
SchoolImpl.java
package com.liwl.dev;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class SchoolImpl implements School {
@Value(value = "${school_name}")
private String name;
@Value(value = "${school_address}")
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "SchoolImpl->" + "name:" + name + ",address:" + address;
}
}
SpringConfig.java
package com.liwl.dev;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class SpringConfig {
public void showMe(){
System.out.println("我是配置類的showMe方法");
}
}
MyTest.java代碼
package com.liwl.dev;
import java.util.Arrays;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
for(String beanName: context.getBeanDefinitionNames()){
String[] aliases = context.getAliases(beanName);
System.out.println(String.format("bean名稱:%s,別名:%s,bean對象:%s", beanName,Arrays.asList(aliases),context.getBean(beanName)));
}
((ConfigurableApplicationContext) context).close();
}
}
F5運行MyTest.java結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$60335662@65c7a252
bean名稱:personImpl,別名:[],bean對象:PersonImpl->name:"liwl",age:30,school:SchoolImpl->name:"江南",address:"無錫"
bean名稱:schoolImpl,別名:[],bean對象:SchoolImpl->name:"江南",address:"無錫"
然後@Component通過value設置bean名稱
//代碼片段
@Component(value = "liwl")
public class PersonImpl implements Person {
...;
}
//SchoolImpl.java代碼片段
@Component(value = "school")
public class SchoolImpl implements School {
...;
}
F5運行MyTest.java結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$60335662@65c7a252
bean名稱:liwl,別名:[],bean對象:PersonImpl->name:"liwl",age:30,school:SchoolImpl->name:"江南",address:"無錫"
bean名稱:school,別名:[],bean對象:SchoolImpl->name:"江南",address:"無錫"
可以看到bean名稱已經對應設置。
這裏有個奇怪的問題:
PersonImpl.java裏面,PersonImpl對School依賴時,直接通過@Autowired使得School類型bean自動注入即可,不需要@Qualifiler,加上也無妨。這個跟之前一個練習試驗不一樣。記錄於2022年03月02日。
2.3.2 @ComponentScan註解和@Controller,@Service,@Repository
@Controller,@Service,@Respository這三個註解實際上區別不大。只是在代碼框架邏輯上進行的人爲區別。
修改PersonImpl.java代碼,把註解@Component換成@Controller
package com.liwl.dev;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@PropertySource(value = {"classpath:all.properties"},encoding = "utf-8")
@Controller(value = "liwl")
public class PersonImpl implements Person {
@Value(value = "${liwl_name}")
private String name;
@Value(value = "${liwl_age}")
private int age;
@Autowired
@Qualifier(value = "school")
private School school;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
@Override
public String toString() {
return "PersonImpl->" + "name:" + name + ",age:" + age + ",school:" + school;
}
}
修改SchoolImpl.java
package com.liwl.dev;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Service(value = "school")
public class SchoolImpl implements School {
@Value(value = "${school_name}")
private String name;
@Value(value = "${school_address}")
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "SchoolImpl->" + "name:" + name + ",address:" + address;
}
}
F5運行結果
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$376ebf8@6340e5f0
bean名稱:liwl,別名:[],bean對象:PersonImpl->name:"liwl",age:30,school:SchoolImpl->name:"江南",address:"無錫"
bean名稱:school,別名:[],bean對象:SchoolImpl->name:"江南",address:"無錫"
總結,上面可以看出實際上被其他註解標註的類,都被當做bean加載到容器裏面,並無區別。
2.3.3 @Component掃描指定的包
在@Component註解源碼能夠看到其被@Repeatable(ComponentScans.class)註解,說明@Component註解能夠同時使用多個。
通過以下三個參數來指定要掃描哪些包:
- value = String
- basePackages = String[]
- basePackageClasses
通過value或者basePackages。value值是字符串,basePackages是字符串數組
通過以下方式來指定要掃描的包
//方式一:
@Component(value = "package")
//方式二:
@Component(basePackages={
"package001",
"package002"
})
//方式三:
@Component(basePackageClasses = "自定義類型")
首先在源碼目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev
下創建三個目錄
- controller
- LiwlController.java
- service
- LiwlService.java
- dao
- LiwlDao.java
LiwlController.java源碼裏面使用註解@Controller,如下:
package com.liwl.dev.controller;
import org.springframework.stereotype.Controller;
@Controller
public class LiwlController {
}
LiwlService.java源碼裏面使用註解@Service,如下:
package com.liwl.dev.service;
import org.springframework.stereotype.Service;
@Service
public class LiwlService {
}
LiwlDao.java源碼裏面使用註解@Repository,如下:
package com.liwl.dev.dao;
import org.springframework.stereotype.Repository;
@Repository
public class LiwlDao {
}
然後修改SpringConfig.java,採用value參數形式
package com.liwl.dev;
import com.liwl.dev.controller.ScanClassToBean;
import com.liwl.dev.dao.ScanClassToBean01;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.liwl.dev")
public class SpringConfig {
}
F5運行MyTest.java結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$6f9fd2da@47af7f3d
bean名稱:liwl,別名:[],bean對象:PersonImpl->name:"liwl",age:30,school:SchoolImpl->name:"江南",address:"無錫"
bean名稱:school,別名:[],bean對象:SchoolImpl->name:"江南",address:"無錫"
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@7c729a55
bean名稱:liwlDao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@3bb9a3ff
bean名稱:liwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@661972b0
修改SpringConfig.java,採用basePackages參數形式
package com.liwl.dev;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages={
"com.liwl.dev.controller",
"com.liwl.dev.service"
})
public class SpringConfig {
public void showMe(){
System.out.println("我是配置類的showMe方法");
}
}
F5運行MyTest.java,結果如下:
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$cec403aa@6cd28fa7
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@614ca7df
bean名稱:liwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@4738a206
可見:
當通過註解@ComponentScan指定要掃描的包時,spring裏面註冊的bean,就是指定包裏面的類對象,以【首字母小寫的類名】作爲bean的名稱。
注意:
指定包名來確認要註冊的bean,存在一個問題。當包名被重命名之後,會導致掃描包失敗。因此一般情況下,使用basePackageClasses的方式來指定要掃描的包。
通過basePackageClasses
使用value或者basePackages來指定要掃描的包時,會因爲包名的變化導致掃描失敗。basePackageClasses的指定方式,能夠解決此類問題。它通過掃描參數指定的類型(自定義類型,接口)所在的包以及其子包中所有的類,來避免包名變化導致無法掃描的問題。
因爲註解@ComponentScan被@Repeatable註解,所以使用basePackageClasses時,必須通過多重註解的方式添加分佈在等級包名下的自定義類型。
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev/controller
下創建ScanClassToBean.java
package com.liwl.dev.controller;
public interface ScanClassToBean {
}
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev/service
下創建ScanClassToBean01.java
package com.liwl.dev.dao;
public interface ScanClassToBean01 {
}
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.controller.ScanClassToBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackageClasses = ScanClassToBean.class)
public class SpringConfig {
}
F5運行MyTest.java結果如下
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$46d705db@4c9f8c13
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@5ae50ce6
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.controller.ScanClassToBean;
import com.liwl.dev.service.ScanClassToBean01;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackageClasses = ScanClassToBean.class)
@ComponentScan(basePackageClasses = ScanClassToBean01.class)
public class SpringConfig {
}
F5運行MyTest.java結果如下
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$a25f16fb@5bd03f44
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@29626d54
bean名稱:liwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@5a63f509
2.3.4 includeFilters使用
1. 指定包含指定註解的類
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev
下創建annotation
目錄
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev/annotation
下創建LiwlAnnotation.java
package com.liwl.dev.annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface LiwlAnnotation{
}
修改LiwlDao.java
package com.liwl.dev.dao;
import com.liwl.dev.annotation.LiwlAnnotation;
import org.springframework.stereotype.Repository;
@Repository
@LiwlAnnotation
public class LiwlDao {
}
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.annotation.LiwlAnnotation;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = LiwlAnnotation.class)
})
public class SpringConfig {
}
F5運行MyTest.java結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$f8c8671a@3e58a80e
bean名稱:liwl,別名:[],bean對象:PersonImpl->name:"liwl",age:30,school:SchoolImpl->name:"江南",address:"無錫"
bean名稱:school,別名:[],bean對象:SchoolImpl->name:"江南",address:"無錫"
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@4fb61f4a
bean名稱:liwlDao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@4fb0f2b9
bean名稱:liwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@79924b
從上面運行結果發現,所有類都被註冊爲bean。爲什麼includeFilters參數沒有生效?這是因爲@ComponentScan有一個參數useDefaultFilters
,該參數默認是true,修改爲false,再觀察結果。
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.annotation.LiwlAnnotation;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(
useDefaultFilters = false,
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = LiwlAnnotation.class)
})
public class SpringConfig {
}
F5運行MyTest.javaJ結果
....
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$c34b74e6@6a400542
bean名稱:liwlDao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@6580cfdd
從上面運行結果發現,之後標準了註解@LiwlAnnotation的類LiwlDao,纔會被註冊到spring裏面
在上面的自定義註解@LiwlAnnotation裏面,無法自定義bean的名稱。下面通過改造該註解,使其具備自定義bean的功能。
修改LiwlAnnotation.java
package com.liwl.dev.annotation;
import java.lang.annotation.*;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface LiwlAnnotation{
@AliasFor(annotation = Component.class)
String value() default "";
}
修改LiwlDao.java
package com.liwl.dev.dao;
import com.liwl.dev.annotation.LiwlAnnotation;
import org.springframework.stereotype.Repository;
@Repository
@LiwlAnnotation(value = "liwldao")
public class LiwlDao {
}
F5運行MyTest.java
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$4ba0f5e7@1700915
bean名稱:liwldao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@21de60b4
從運行結果能夠看出,spring已經註冊了名爲liwldao的bean
2. 指定包含指定類型的類
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.service.LiwlService;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(
useDefaultFilters = false,
includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = LiwlService.class)
})
public class SpringConfig {
}
F5運行MyTest.java結果如下
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$776b2c0c@c267ef4
bean名稱:liwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@30ee2816
從結果可以看出,spring只註冊了LiwlService的bean。
2.3.5 自定義過濾器
本部分待補充
2.3.6 @ComponentScans重複使用
@ComponentScan在定義中使用了@Repeatable註解,表示該註解可以重複使用。一般使用方式如下:
@ComponentScan(backPacagekClasses = 自定義類型.class)
@ComponentScan(
useDefaultFilters = false,
includeFilters = {
@CompontScan.Filter(type=Filter.Type.ASSIGNABLE_TYPE,classes=自定義類)
})
或者
@ComponentScans({
@ComponentScan(backPacagekClasses = 自定義類型.class)
@ComponentScan(
useDefaultFilters = false,
includeFilters = {
@CompontScan.Filter(type=Filter.Type.ASSIGNABLE_TYPE,classes=自定義類)
})})
3. @Import
@Import註解跟xml配置的<import>
標籤作用一樣,允許通過它引入:
- @Configuration標註的類
- ImportSelector接口和ImportBeanDefinitionRegistrar接口實現
- @Component註解的普通類
總的來說:@Import可以用來批量導入需要註冊的各種類,普通類,配置類,完成bean的註冊。
@Import的參數value常見的5種用法
- value爲普通的類
- value爲@Configuration標註的類
- value爲@ComponetentScan標註的類
- value爲ImportBeanDefinionRegistart接口類型
- value爲ImportSelector接口類型
- value爲DeferredImportSelector接口類型
3.1 value爲普通的類
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.dao.LiwlDao;
import com.liwl.dev.service.LiwlService;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan(value = "com.liwl.dev.controller")
public class SpringConfig {
}
修改MyTest.java
package com.liwl.dev;
import java.util.Arrays;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println("\n...");
for(String beanName: context.getBeanDefinitionNames()){
String[] aliases = context.getAliases(beanName);
if(beanName.contains("org.springframework")){
continue;
}
System.out.println(String.format("bean名稱:%s,別名:%s,bean對象:%s", beanName,Arrays.asList(aliases),context.getBean(beanName)));
}
((ConfigurableApplicationContext) context).close();
}
}
修改LiwlService.java和LiwlDao.java,去掉全部在註解,變爲普通類
package com.liwl.dev.dao;
import com.liwl.dev.annotation.LiwlAnnotation;
import org.springframework.stereotype.Repository;
public class LiwlDao {
}
package com.liwl.dev.service;
import org.springframework.stereotype.Service;
public class LiwlService {
}
F5運行MyTest.java結果如下
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$e5da1911@35047d03
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@49b0b76
從結果可以發現,只有liwlController的bean註冊到了spring容器裏。
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.dao.LiwlDao;
import com.liwl.dev.service.LiwlService;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan(value = "com.liwl.dev.controller")
@Import({LiwlService.class,LiwlDao.class})
public class SpringConfig {
}
F5運行MyTest.java結果如下
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$6fa9b108@e056f20
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@4b0b0854
bean名稱:com.liwl.dev.service.LiwlService,別名:[],bean對象:com.liwl.dev.service.LiwlService@19bb07ed
bean名稱:liwldao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@10e41621
從結果可以看出,已經通過@Import註解,向spring容器註冊了普通的類LiwlService和LiwlDao
此時也可以在要被註冊的LiwlService上使用註解@Compoent(value="xxx")的方式,爲bean指定名稱,比如:
修改LiwlService.java
package com.liwl.dev.service;
import org.springframework.stereotype.Service;
@Service(value = "liwlservice")
public class LiwlService {
}
F5運行結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$6f60a7f@17046283
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@5bd03f44
bean名稱:liwlservice,別名:[],bean對象:com.liwl.dev.service.LiwlService@29626d54
bean名稱:com.liwl.dev.dao.LiwlDao,別名:[],bean對象:com.liwl.dev.dao.LiwlDao@5a63f509
從運行結果發現,此時已經給LiwlService要註冊的bean,設置了名稱liwlservice
總結:
按照模塊的方式進行導入,需要哪個某塊就導入那個某塊,不需要的時候,直接修改一下總的配置類,調整@Import的value就可以了。
3.2 value爲@Configuration標註的配置類
這種情況主要發生在項目很大時,需要劃分很多模塊,會按照模塊獨立開發,每個某塊在maven中表現爲一個個構建,然後通過座標的方式引入需要引入的模塊。
假如項目中有2個模板,2個模塊都有各自的配置類。
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev
下創建config目錄
在config目錄下創建SpringSubConfig01.java和SpringSubConfig02.java文件
修改SpringSubConfig01.java
package com.liwl.dev.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringSubConfig01 {
@Bean(value = "sprintsubconfig01_show")
public String show(){
return "我是SpringSubconfig01配置類";
}
}
修改SpringSubConfig02.java
package com.liwl.dev.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringSubConfig02 {
@Bean(value = "springsubconfig02_show")
public String show(){
return "我是SpringSubConfig02配置類";
}
}
修改主配置文件SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.config.SpringSubConfig01;
import com.liwl.dev.config.SpringSubConfig02;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({SpringSubConfig01.class,SpringSubConfig02.class})
public class SpringConfig {
}
F5運行MyTest.java結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$7afc888b@6193932a
bean名稱:com.liwl.dev.config.SpringSubConfig01,別名:[],bean對象:com.liwl.dev.config.SpringSubConfig01$$EnhancerBySpringCGLIB$$402ae426@647fd8ce
bean名稱:sprintsubconfig01_show,別名:[],bean對象:我是SpringSubconfig01配置類
bean名稱:com.liwl.dev.config.SpringSubConfig02,別名:[],bean對象:com.liwl.dev.config.SpringSubConfig02$$EnhancerBySpringCGLIB$$788d8747@159f197
bean名稱:springsubconfig02_show,別名:[],bean對象:我是SpringSubConfig02配置類
從結果可以看出,2個模塊的子配置類,已經成功導入主配置,並且註冊到spring容器。
3.3 value爲@ComponentScan標註的類
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev/controller
下創建LiwlScanClass01.java
package com.liwl.dev.controller;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class LiwlScanClass01 {
}
在目錄/root/liwldev/java/web/springframe/SpringAnnotation/src/main/java/com/liwl/dev/service
下創建LiwlScanClass02.java
package com.liwl.dev.service;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class LiwlScanClass02 {
}
修改SpringConfig.java
package com.liwl.dev;
import com.liwl.dev.controller.LiwlScanClass01;
import com.liwl.dev.service.LiwlScanClass02;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({LiwlScanClass01.class,LiwlScanClass02.class})
public class SpringConfig {
}
F5運行結果
...
bean名稱:springConfig,別名:[],bean對象:com.liwl.dev.SpringConfig$$EnhancerBySpringCGLIB$$3a9f6330@29626d54
bean名稱:liwlController,別名:[],bean對象:com.liwl.dev.controller.LiwlController@5a63f509
bean名稱:liwlservice,別名:[],bean對象:com.liwl.dev.service.LiwlService@6e4784bc
bean名稱:com.liwl.dev.controller.LiwlScanClass01,別名:[],bean對象:com.liwl.dev.controller.LiwlScanClass01@34b7ac2f
bean名稱:com.liwl.dev.service.LiwlScanClass02,別名:[],bean對象:com.liwl.dev.service.LiwlScanClass02@e056f20
從運行結果來看,已經成功註冊了了包controller和包service包的類。
目錄下的接口未註冊,並且接口使用@ComponentScan是錯誤的