01 Spring IoC 依赖查找

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

        }
    }


}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DreamCatcher

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

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

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

打赏作者

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

抵扣说明:

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

余额充值