您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring單元測試控制Bean注入的方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在配置文件中指定要注入的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文件就可以實現注入
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 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來進行注入,具體如下
二者用法基本一樣,只不過@Configuration可以控制注入的Bean是不是一個代理對象,如果是代理對象,那么調用@Bean方法返回的都是同一個對象,否則就不是同一個對象。
在默認情況下,@Configuration注入的對象是一個代理對象
默認情況,proxyBeanMethods = true
@Configuration(proxyBeanMethods = true) public class Cat { @Bean public Cat bigCat() { return new Cat(); } }
得到這個對象,然后調用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已經是一個代理對象了,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(); } }
其他代碼不變,可以發現沒有進行代理。
com.ttpfx.entity.t2.Cat@62fdb4a6
---------------------
com.ttpfx.entity.t2.Cat@11e21d0e
com.ttpfx.entity.t2.Cat@1dd02175
false
如果使用@Component,那么就相當于@Configuration的proxyBeanMethods 設置為false
我們可以讓一個類實現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進行導入
@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); } }
輸出如下,可以發現使用@Import標注的類也會被注入。使用@Import導入的類,名稱為全類名,如果重復導入,那么后面覆蓋前面。要指定名稱,那么就在對應的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
可以直接通過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
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); } }
輸出如下,可以發現selectImports返回的String字符串中的內容會進行注入
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可以進行注入,只需要在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
實現這個接口,通過方法上面的參數可以進行注入
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); } }
輸出如下,可以發現實現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
“Spring單元測試控制Bean注入的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。