02 Spring IoC 依赖注入

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问题解决

解决方式:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamCatcher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值