1、根據Bean名稱查找
(1)建立執行個體類
package org.binsoft.thinking.in.spring.ioc.overview.domain;
/**
* TODO
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 12:05
*/
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
(2)在類路徑下的resources建立目錄 META-INF,并建立spring的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="org.binsoft.thinking.in.spring.ioc.overview.domain.User">
<property name="id" value="1"/>
<property name="name" value="彬少"/>
</bean>
</beans>
(3)根據名稱實時查找
beanFactory.getBean
package org.binsoft.thinking.in.spring.ioc.overview.dependency.lookup;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 依賴查找執行個體
* 1. 通過名稱的方式來查找
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置檔案
// 啟動 Spring 應用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
lookupInRealTime(beanFactory);
}
private static void lookupInRealTime(BeanFactory beanFactory) {
User user = (User) beanFactory.getBean("user");
System.out.println("實時查找:" + user);
}
}
(4)根據名稱延遲查找
主要通過ObjectFactory接口實作:
主要實作的FactoryBean為:
org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean
通過源碼分析,此類有兩個重要的地方:
- 目标Bean名稱,需要外部進行配置指定
@Nullable
private String targetBeanName;
實作ObjectFactory接口的私有靜态内部類TargetBeanObjectFactory,代理BeanFactory來進行Bean執行個體的查找:
/**
* Independent inner class - for serialization purposes.
*/
@SuppressWarnings("serial")
private static class TargetBeanObjectFactory implements ObjectFactory<Object>, Serializable {
private final BeanFactory beanFactory;
private final String targetBeanName;
public TargetBeanObjectFactory(BeanFactory beanFactory, String targetBeanName) {
this.beanFactory = beanFactory;
this.targetBeanName = targetBeanName;
}
@Override
public Object getObject() throws BeansException {
return this.beanFactory.getBean(this.targetBeanName);
}
}
在配置檔案中,對ObjectFactoryCreatingFactoryBean進行配置:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="org.binsoft.thinking.in.spring.ioc.overview.domain.User">
<property name="id" value="1"/>
<property name="name" value="彬少"/>
</bean>
<bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName" value="user"/>
</bean>
</beans>
通過ObjectFactory的 T getObject() throws BeansException; 方法來查找Bean執行個體。
package org.binsoft.thinking.in.spring.ioc.overview.dependency.lookup;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 依賴查找執行個體
* 1. 通過名稱的方式來查找
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置檔案
// 啟動 Spring 應用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
lookupInLazy(beanFactory);
}
private static void lookupInLazy(BeanFactory beanFactory) {
ObjectFactory<User> objectFactory = (ObjectFactory<User>) beanFactory.getBean("objectFactory");
User user = objectFactory.getObject();
System.out.println("延遲查找:" + user);
}
}
從此過程中,可以看出, ObjectFactory 對象并不是直接傳回了實際的Bean,而是一個Bean的查找代理。當得到ObjectFactory對象時,相當于Bean沒有被建立,隻有當調用getObject()方法時,才會觸發Bean執行個體化等生命周期 。
2、根據Bean類型查找
(1)單個Bean對象
主要通過BeanFactory的
<T> T getBean(Class<T> requiredType) throws BeansException;
方法來實作,因為涉及到泛型,是以要求Spring的版本為3.0及以上:
并通過注釋,可以看出,需要利用ListableBeanFactory:
package org.binsoft.thinking.in.spring.ioc.overview.dependency.lookup;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 依賴查找執行個體
* 1. 通過名稱的方式來查找
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置檔案
// 啟動 Spring 應用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
//按照類型查找
lookupByType(beanFactory);
}
private static void lookupByType(BeanFactory beanFactory) {
User user = beanFactory.getBean(User.class);
System.out.println("實時查找:" + user);
}
}
(2)集合Bean對象
主要通過ListableBeanFactory接口的
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
方法
package org.binsoft.thinking.in.spring.ioc.overview.dependency.lookup;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 依賴查找執行個體
* 1. 通過名稱的方式來查找
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置檔案
// 啟動 Spring 應用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
//按照類型查找集合對象
lookupCollectionByType(beanFactory);
}
private static void lookupCollectionByType(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory listableBeanfactory = (ListableBeanFactory) beanFactory;
Map<String, User> users = listableBeanfactory.getBeansOfType(User.class);
System.out.println("查找到的所有的 User 集合對象:" + users);
}
}
}
3、根據Bean名稱+類型查找
主要通過BeanFactory接口的
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
方法來實作,最主要的一點是,此方法會進行一定程度的類型安全檢查:會抛出異常:BeanNotOfRequiredTypeException
4、根據Java注解查找
主要通過ListableBeanFactory接口的
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
方法來實作:
(1)建立一個注解Super
package org.binsoft.thinking.in.spring.ioc.overview.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Super {
}
(2)建立SuperUser對象并繼承自User,并為Super對象标注注解@Super
package org.binsoft.thinking.in.spring.ioc.overview.domain;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
/**
* TODO
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 13:14
*/
@Super
public class SuperUser extends User {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "SuperUser{" +
"address='" + address + '\'' +
"} " + super.toString();
}
}
(3)通過Spring XML檔案配置Super對象,并指定屬性:parent="user"和 primary="true"
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="org.binsoft.thinking.in.spring.ioc.overview.domain.User">
<property name="id" value="1"/>
<property name="name" value="彬少"/>
</bean>
<bean id="superUser" class="org.binsoft.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user"
primary="true">
<property name="address" value="北京"/>
</bean>
<bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName" value="user"/>
</bean>
</beans>
(4)通過getBeansWithAnnotation方法類查找:
package org.binsoft.thinking.in.spring.ioc.overview.dependency.lookup;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 依賴查找執行個體
* 1. 通過名稱的方式來查找
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置檔案
// 啟動 Spring 應用上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
//按照注解查找
lookupByAnnotationType(beanFactory);
}
private static void lookupByAnnotationType(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
Map<String, Object> users = listableBeanFactory.getBeansWithAnnotation(Super.class);
System.out.println("查找标注 @Super 的所有User集合對象:" + users);
}
}
}