1、根据Bean名称注入
(1)创建一个用户仓储实体 UserRepository
package org.binsoft.thinking.in.spring.ioc.overview.repository;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import java.util.Collection;
/**
* 用户信息仓储
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 19:15
*/
public class UserRepository {
//注入一个集合对象
private Collection<User> users; //自定义Bean
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
}
(2)在META-INF目录下,创建Spring XML配置文件 dependency-injection-context.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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<import resource="dependency-lookup-context.xml"/>
<bean id="userRepository" class="org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository" >
<!-- 手动配置 -->
<property name="users">
<util:list>
<ref bean="superUser"/>
<ref bean="user"/>
</util:list>
</property>
</bean>
</beans>
(3)取得注入的对象:会按照手动注入的对象的顺序来打印
package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
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;
/**
* 依赖注入示例
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyInjectionDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
System.out.println(userRepository.getUsers());
//会按照手动注入的对象的顺序来打印
}
}
2、根据Bean类型注入
(1)设置按照类型来自动注入
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<import resource="dependency-lookup-context.xml"/>
<bean id="userRepository" class="org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository"
autowire="byType"> <!-- Auto Wiring -->
<!-- 手动配置 -->
<!--<property name="users">-->
<!--<util:list>-->
<!--<ref bean="superUser"/>-->
<!--<ref bean="user"/>-->
<!--</util:list>-->
<!--</property>-->
</bean>
</beans>
(2)取得注入的对象:按照Bean定义的顺序打印:
3、注入非Bean对象,因通过BeanFactory通过类型查不出来
注:非Bean,可以指的是没有Bean的名称
(1)在UserRepository中,注入BeanFactory
package org.binsoft.thinking.in.spring.ioc.overview.repository;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import java.util.Collection;
/**
* 用户信息仓储
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 19:15
*/
public class UserRepository {
//注入一个集合对象
private Collection<User> users; //自定义Bean
private BeanFactory beanFactory; // 内建非Bean 对象(依赖)
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
}
(2)取得依赖的userRepository.getBeanFactory(),并不是一个Bean对象,而是一个内置对象,
其实属于容器的内建的一些依赖
package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
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;
/**
* 依赖注入示例
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyInjectionDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
System.out.println(userRepository.getUsers());
//依赖注入(内建依赖)
System.out.println(userRepository.getBeanFactory());// 说明不是Bean对象,而是一个内建的对象
System.out.println(userRepository.getBeanFactory() == beanFactory); // false
}
}
下图说明,userRepository中的beanFactory只是一个内置的对象,其实就是容器内建的一些依赖
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
此语句返回的 beanFactory其实为:org.springframework.context.support.ClassPathXmlApplicationContext@3fb6a447
此对象实例里面组合了一个beanFactory实例:org.springframework.beansFactory.support.DefaultListableBeanFactory@25d250c6
而 userRepository.getBeanFactory()返回的userRepository对象中通过类型自动注入的beanFactory实例 为:org.springframework.beans.factory.support.DefaultListableBeanFactory@25d250c6
所以,此条语句 userRepository.getBeanFactory() == beanFactory 数据结果为 false.
那么通过依赖查找,查找userRepository中注入的BeanFactory 是否可以查找到该对象?
package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
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;
/**
* 依赖注入示例
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyInjectionDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
//System.out.println(userRepository.getUsers());
//依赖注入
System.out.println(userRepository.getBeanFactory());// 说明不是Bean对象,而是一个内建的对象
System.out.println(userRepository.getBeanFactory() == beanFactory); // false
//依赖查找
System.out.println(beanFactory.getBean(BeanFactory.class)); //抛出异常:NoSuchBeanDefinitionException,那这个Bean到底哪里来的呢?
//这也说明一个问题,依赖查找和依赖注入并不一样,依赖查找和依赖注入都属于依赖,但是不是同源的
}
}
事实证明,会抛出异常:NoSuchBeanDefinitionException
也充分说明了:依赖查找和依赖注入并不一样,依赖查找和依赖注入都属于依赖,但不是同源的
4、注入类型
(1)实时注入
上面的示例都是实时注入
(2)延迟注入
通过ObjectFactory注入
package org.binsoft.thinking.in.spring.ioc.overview.repository;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import java.util.Collection;
/**
* 用户信息仓储
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 19:15
*/
public class UserRepository {
//注入一个集合对象
private Collection<User> users; //自定义Bean
private BeanFactory beanFactory; // 内建非Bean 对象(依赖)
private ObjectFactory<User> objectFactory;
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public ObjectFactory<User> getObjectFactory() {
return objectFactory;
}
public void setObjectFactory(ObjectFactory<User> objectFactory) {
this.objectFactory = objectFactory;
}
}
取得延迟注入的对象:
package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
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;
/**
* 依赖注入示例
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyInjectionDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
ObjectFactory userFactory = userRepository.getObjectFactory();
//SuperUser{address='北京'} User{id=1, name='彬少'}
System.out.println(userFactory.getObject());
}
}
如果延迟注入一个ApplicationContext对象,那么此对象到底会是什么?
package org.binsoft.thinking.in.spring.ioc.overview.repository;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import java.util.Collection;
/**
* 用户信息仓储
*
* @author Administrator
* @version 1.0
* @date 2021/1/1 19:15
*/
public class UserRepository {
//注入一个集合对象
private Collection<User> users; //自定义Bean
private BeanFactory beanFactory; // 内建非Bean 对象(依赖)
private ObjectFactory<ApplicationContext> objectFactory;
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public ObjectFactory<ApplicationContext> getObjectFactory() {
return objectFactory;
}
public void setObjectFactory(ObjectFactory<ApplicationContext> objectFactory) {
this.objectFactory = objectFactory;
}
}
package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;
import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
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;
/**
* 依赖注入示例
*
* @author binsoft
* @version 1.0
* @date 2021/1/1 11:53
*/
public class DependencyInjectionDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
System.out.println(userRepository.getUsers());
ObjectFactory userFactory = userRepository.getObjectFactory();
//ClassPathXmlApplicationContext
System.out.println(userFactory.getObject());
System.out.println(userFactory.getObject() == beanFactory); //true
}
}
说明 objectFactory 根据类型 autowire的时候,注入了一个ApplicationContext(ClassPathXmlApplicationContext)
同时可以看出一些隐含的知识:
BeanFactoryPostProcessor 回调 BeanFactory 的时机较早,早于 ApplicationContextAware。BeanFactoryPostProcessor 属于 BeanFactory 生命周期,而 ApplicationContextAware 属于 Bean 生命周期。
BeanFactoryPostProcessor 传递的是 BeanFactory,而 ApplicationContextAware 则是 ApplicationContext,对象并非同一个,前面也提到了 ApplicationContext 会 Wrap BeanFactory 示例
5、学习过程中 IDE问题解决
解决方式: