通過註解裝配Spring Bean(組件掃描)
Annotation
通過註解(Annotation)去裝配Soring Bean,可以減少對XML文件的配置,註解功能更爲強大,他既能實現XML的功能,也能提供自動裝配的功能。
方式
方式 | 作用 |
---|---|
組件掃描(@Component與@ComponentScan) | 通過定義資源的方式,讓Spring IOC容器掃描對應的包,從而把Bean裝配出來 |
自動裝配(@Autowired) | 通過註解定義,使得一些依賴關係可以通過註解完成 |
組件掃描
使用@Component裝配Bean
- 首先定義一個POJO類,Role.java
package com.ssm.annotation.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "role")
public class Role {
@Value("1")
private Long idLong;
@Value("roleName1")
private String roleNameString;
@Value("note1")
private String noteString;
public Long getIdLong() {
return idLong;
}
public void setIdLong(Long idLong) {
this.idLong = idLong;
}
public String getRoleNameString() {
return roleNameString;
}
public void setRoleNameString(String roleNameString) {
this.roleNameString = roleNameString;
}
public String getNoteString() {
return noteString;
}
public void setNoteString(String noteString) {
this.noteString = noteString;
}
@Override
public String toString() {
return "Role [idLong=" + idLong + ", roleNameString=" + roleNameString + ", noteString=" + noteString + "]";
}
}
1.註解@Component代表Spring IoC會把這個類掃描生成Bean實例,
其中value代表這個類在Spring中的ID,value可以省略不寫@Component("role"),也可以直接寫成@Component,Spring IOC會默認爲類名,但是id會變成首字母小寫的類名(”role“)。
2.註解@Value代表是值的注入。
- 定義一個Java Config類,好讓Spring IOC知道要去哪裏掃描對象
package com.ssm.pojo;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class PojoConfig {}
1.包名要和POJO保持一致(就是Java Conofig類要和POJO類在同一個包下)。
2.@ComponentScan代表進行掃描,默認是掃描當前包的路徑。
- 測試類
package com.ssm.pojo.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ssm.pojo.PojoConfig;
import com.ssm.pojo.Role;
public class test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role = context.getBean(Role.class);
System.out.print(role.toString());
}
}
這裏使用AnnotationConfigApplicationContext生成IOC容器,並獲取PojoConfig.java類中掃描的對象。
- 運行結果
Role [idLong=1, roleNameString=roleName1, noteString=note1]
通過上面的簡單編寫你會發現兩個弊端:
- 對於@ComponentScan註解,你會發現他只是掃描所在java類的包,不能掃描指定的包
- 上面的注入只有值的注入,但是大部分需要的是對象的注入
所以爲了解決這第一個問題(包的掃描),我們可以在@ComponentScan中引用兩個配置項
- basePackages
- basePackageClasses
配置項 | 作用 |
---|---|
basePackages | 可以配置一個Java包的數組,Spring會根據配置去掃描對應的包和子包,把配置好的Bean裝配進來 |
basePackageClasses | 可以配置多個Java類,會根據類所在的包,爲該包和子包進行掃描裝配對應配置的Bean |
@ComponentScan的使用
- 實體類POJO還是上面的Role.java
- 然後定義一個service接口
package com.ssm.annotation.service;
import com.ssm.annotation.pojo.Role;
public interface RoleService {
public void printRoleInfo(Role role);
}
- 實現RoleService接口
package com.ssm.annotation.service.impl;
import org.springframework.stereotype.Component;
import com.ssm.annotation.pojo.Role;
import com.ssm.annotation.service.RoleService;
@Component
public class RoleServiceImpl implements RoleService{
@Override
public void printRoleInfo(Role role) {
System.out.println(role.toString());
}
}
- 對Java Config類配置@ComponentScan
package com.ssm.annotation.config;
import org.springframework.context.annotation.ComponentScan;
import com.ssm.annotation.pojo.Role;
import com.ssm.annotation.service.impl.RoleServiceImpl;
//通過@ComponentScan中的basePackageClasses配置項,可以獲取配置的類所在的包,爲包和子包進行掃描裝配對應配置的Bean
//@ComponentScan(basePackageClasses = {Role.class,RoleServiceImpl.class})
//通過@ComponentS阿產能中的basePackages配置項,可以配置一個java包的數組,Spring會根據他的配置掃描對應的包和子包
//@ComponentScan(basePackages = {"com.ssm.annotation.pojo","com.ssm.annotation.service"})
//組合使用
@ComponentScan(basePackageClasses = {Role.class,RoleServiceImpl.class},basePackages = {"com.ssm.annotation.pojo","com.ssm.annotation.service"})
public class PojoConfig {}
上面通過三種方式進行了配置:
1.basePackageClassess採用的是對包的掃描,他會掃描該包和子包,將配置好的Bean裝配進來
2.basePackages 會對java包的數組進行掃描,並掃描對應的包和子包
注意:
對於掃描包的定義,可以採用任意一個@ComponentScan去定義,但是最好只定義一個@ComponentScan,
因爲每定義一個@ComponentScan,Spring就會爲所定義的類去生成一個新的對象,也就是所配置的Bean將會生成多個實例。
對於同一個@ComponentScan中部的basePackageClasses和basePackages,Spring會進行專門的區分,
也就是說在同一個@ComponentScan中即使你重複定義相同的包或者子包,也不會造成因同一個Bean的多次掃描,而導致一次配置會生成多個對象的情況。
- 測試類
package com.ssm.annotation.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ssm.annotation.config.PojoConfig;
import com.ssm.annotation.pojo.Role;
import com.ssm.annotation.service.RoleService;
public class AnnotationTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role = context.getBean(Role.class);
RoleService roleService =context.getBean(RoleService.class);
roleService.printRoleInfo(role);
}
}
- 運行結果
Role [idLong=1, roleNameString=roleName1, noteString=note1]
但是還沒有解決對象注入的問題,下一節使用自動裝配(@AutoWired)解對象注入問題。