Spring - 裝配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)解對象注入問題。

自動裝配-@AutoWired-下一節

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章