Spring單元測試控制Bean注入的方式
通過xml文件進行注入
在配置文件中指定要注入的bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.ttpfx.entity.Dog">
<property name="name" value="旺財"/>
<property name="age" value="18"/>
</bean>
</beans>
然后spring加載這個xml文件就可以實現(xiàn)注入
public class SpringTest1 {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
輸出為
dog
通過xml加注解方式進行注入
編寫xml配置文件,里面指定要掃描的包
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 掃描 com.ttpfx.entity.t2 包下的所有bean-->
<context:component-scan base-package="com.ttpfx.entity.t2"/>
</beans>
然后在要注入的bean上加入Component注解即可(如果里面方法上面有@Bean,那么也會進行處理)
@Component
public class Cat {
}
public class SpringTest2 {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext2.xml");
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
輸出為
cat
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
通過注解進行注入
可以不使用xml文件,通過@ComponentScan注解來完成定義掃描路徑的功能
@ComponentScan(basePackages = "com.ttpfx.entity.t3")
public class SpringConfig3 {
}
public class SpringTest3 {
public static void main(String[] args) {
ApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig3.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
使用@ComponentScan也會將自身加入到容器中。我們可以在方法上加入@Bean來進行注入,具體如下
@Component和@Configuration的區(qū)別
二者用法基本一樣,只不過@Configuration可以控制注入的Bean是不是一個代理對象,如果是代理對象,那么調(diào)用@Bean方法返回的都是同一個對象,否則就不是同一個對象。
在默認情況下,@Configuration注入的對象是一個代理對象
默認情況,proxyBeanMethods = true
@Configuration(proxyBeanMethods = true)
public class Cat {
@Bean
public Cat bigCat() {
return new Cat();
}
}
得到這個對象,然后調(diào)用bigCat這個方法
public class SpringTest2 {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext2.xml");
Cat cat = ioc.getBean("cat", Cat.class);
System.out.println(cat);
Cat bigCat1 = cat.bigCat();
Cat bigCat2 = cat.bigCat();
System.out.println("---------------------");
System.out.println(bigCat1);
System.out.println(bigCat2);
System.out.println(bigCat1 == bigCat2);
}
}
這時返回Cat已經(jīng)是一個代理對象了,bigCat返回的都是同一個對象,就是單例模式的。
com.ttpfx.entity.t2.Cat$$EnhancerBySpringCGLIB$$bc3ad26b@4c1d9d4b
---------------------
com.ttpfx.entity.t2.Cat@7b227d8d
com.ttpfx.entity.t2.Cat@7b227d8d
true
如果將proxyBeanMethods 改成false,情況如下
@Configuration(proxyBeanMethods = false)
public class Cat {
@Bean
public Cat bigCat() {
return new Cat();
}
}
其他代碼不變,可以發(fā)現(xiàn)沒有進行代理。
com.ttpfx.entity.t2.Cat@62fdb4a6
---------------------
com.ttpfx.entity.t2.Cat@11e21d0e
com.ttpfx.entity.t2.Cat@1dd02175
false
如果使用@Component,那么就相當于@Configuration的proxyBeanMethods 設(shè)置為false
使用FactoryBean
我們可以讓一個類實現(xiàn)FactoryBean,這個接口有一個getObject方法,如果一個使用@Bean標記的方法返回FactoryBean,那么最終返回的是FactoryBean的getObject方法返回的值
public class PeopleFactory implements FactoryBean<People> {
@Override
public People getObject() throws Exception {
return new People();
}
@Override
public Class<?> getObjectType() {
return People.class;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
@Component
public class People {
@Bean
public PeopleFactory peopleFactory(){
return new PeopleFactory();
}
}
此時獲取peopleFactory,它的類型如下,是一個People類型
com.ttpfx.entity.t3.People@587c290d
通過@Import導(dǎo)入
可以使用@Import進行導(dǎo)入
@Import({User.class})
public class SpringConfig4 {
}
public class SpringTest4 {
public static void main(String[] args) {
ApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig4.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
輸出如下,可以發(fā)現(xiàn)使用@Import標注的類也會被注入。使用@Import導(dǎo)入的類,名稱為全類名,如果重復(fù)導(dǎo)入,那么后面覆蓋前面。要指定名稱,那么就在對應(yīng)的bean上面使用@Component即可
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig4
com.ttpfx.entity.t4.User
手動注入(registerBean)
可以直接通過GenericApplicationContext這個類的registerBean方法進行注入
public class SpringTest5 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig5.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
System.out.println("-----------------------");
ioc.registerBean("monster01", Monster.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
輸出如下
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig5
-----------------------
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig5
monster01
通過ImportSelector進行注入
定義一個類實現(xiàn)ImportSelector
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.ttpfx.entity.t6.Pig"};
}
}
@Import({MyImportSelector.class})
public class SpringConfig6 {
}
public class SpringTest6 {
public static void main(String[] args) {
ApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig6.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
}
}
輸出如下,可以發(fā)現(xiàn)selectImports返回的String字符串中的內(nèi)容會進行注入
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig6
com.ttpfx.entity.t6.Pig
通過ImportBeanDefinitionRegistrar進行注入
通過ImportBeanDefinitionRegistrar可以進行注入,只需要在registerBeanDefinitions方法中使用BeanDefinitionRegistry的registerBeanDefinition方法即可
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
ImportBeanDefinitionRegistrar.super.registerBeanDefinitions(importingClassMetadata, registry, importBeanNameGenerator);
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Manager.class).getBeanDefinition();
registry.registerBeanDefinition("manager", beanDefinition);
ImportBeanDefinitionRegistrar.super.registerBeanDefinitions(importingClassMetadata, registry);
}
}
public class SpringTest7 {
public static void main(String[] args) {
ApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig7.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
Manager bean = ioc.getBean(Manager.class);
System.out.println(bean);
}
}
代碼輸出如下
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig7
manager
com.ttpfx.entity.t7.Manager@1d8d30f7
通過BeanDefinitionRegistryPostProcessor進行注入
實現(xiàn)這個接口,通過方法上面的參數(shù)可以進行注入
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Employee.class).getBeanDefinition();
registry.registerBeanDefinition("employee", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
@Import({MyBeanDefinitionRegistryPostProcessor.class})
public class SpringConfig8 {
}
public class SpringTest8 {
public static void main(String[] args) {
ApplicationContext ioc = new AnnotationConfigApplicationContext(SpringConfig8.class);
Arrays.stream(ioc.getBeanDefinitionNames()).forEach(System.out::println);
System.out.println("-----------------");
Employee bean = ioc.getBean(Employee.class);
System.out.println(bean);
}
}
輸出如下,可以發(fā)現(xiàn)實現(xiàn)BeanDefinitionRegistryPostProcessor的這個類也被注入了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
springConfig8
com.ttpfx.entity.t8.MyBeanDefinitionRegistryPostProcessor
employee
-----------------
com.ttpfx.entity.t8.Employee@58c1670b
到此這篇關(guān)于Spring注入bean的方式詳細講解的文章就介紹到這了,更多相關(guān)Spring注入bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot前后臺數(shù)據(jù)交互的示例代碼
這篇文章主要介紹了springboot前后臺數(shù)據(jù)交互的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
Spring Boot異步調(diào)用@Async過程詳解
這篇文章主要介紹了Spring Boot異步調(diào)用@Async過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
Spring Boot不同版本Redis設(shè)置JedisConnectionFactory詳解
本文章向大家介紹Spring Boot不同版本Redis設(shè)置JedisConnectionFactory,主要內(nèi)容包括1.X 版本、2.X 版本、2.、基本概念、基礎(chǔ)應(yīng)用、原理機制和需要注意的事項等,并結(jié)合實例形式分析了其使用技巧,希望通過本文能幫助到大家理解應(yīng)用這部分內(nèi)容2023-09-09
Java實現(xiàn)圖片上傳到服務(wù)器并把上傳的圖片讀取出來
在各大網(wǎng)站上都可以實現(xiàn)上傳頭像功能,可以選擇自己喜歡的圖片做頭像,從本地上傳,今天小編給大家分享Java實現(xiàn)圖片上傳到服務(wù)器并把上傳的圖片讀取出來,需要的朋友參考下2017-02-02

