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);
}
}
}