作者:Grey

原文地址:

语雀

博客园

依赖查找

Spring IoC 依赖查找分为以下几种方式

  • 根据 Bean 名称查找

    • 实时查找
    • 延迟查找
  • 根据 Bean 类型查找

    • 单个 Bean 对象
    • 集合 Bean 对象
  • 根据 Bean 名称 + 类型查找

  • 根据 Java 注解查找

    • 单个 Bean 对象
    • 集合 Bean 对象

以下示例基于spring-framework 5.2.13.RELEASE 版本, 通过Maven管理项目

根据Bean名称实时查找

pom.xml 文件引入如下依赖


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>

定义一个User作为Domain

public class User {
private Long id;
private String name;
// set / get / toString方法略
}

在resources目录下建立META—INF目录,同时新建一个dependency-lookup.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"> </beans>

在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.snippets.spring.ioc.overview.dependency.domain.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
</bean> </beans>

新建测试类

package org.snippets.spring.ioc.overview.dependency.lookup;

/**
* 通过名称查找
*/
public class DependencyLookup {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup.xml");
lookupRealtime(beanFactory);
} // 实时查找(按Bean名称)
private static void lookupRealtime(BeanFactory beanFactory) {
User user = (User) beanFactory.getBean("user");
System.out.println(user);
}
}

输出结果

User{id=1, name='张三'}

根据Bean名称延迟查找

在上例中的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.snippets.spring.ioc.overview.dependency.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>

新建测试类


public class DependencyLookup {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup.xml");
lookupLazy(beanFactory);
} // 延迟查找(按Bean名称)
private static void lookupLazy(BeanFactory beanFactory) {
ObjectFactory<User> objectFactory = (ObjectFactory<User>) beanFactory.getBean("objectFactory");
User user = objectFactory.getObject();
System.out.println(user);
}
}

运行结果

User{id=1, name='张三'}

根据Bean类型查找单个对象


private static void lookupByTypeSingle(BeanFactory beanFactory){
User user=beanFactory.getBean(User.class);
System.out.println(user);
}

根据Bean类型查询集合对象

private static void lookupByTypeCollection(BeanFactory beanFactory){
if(beanFactory instanceof ListableBeanFactory){
ListableBeanFactory beanFactory1=(ListableBeanFactory)beanFactory;
Map<String, User> users=beanFactory1.getBeansOfType(User.class);
System.out.println(users);
}
}

根据Java注解来查询多个对象

首先我们定义一个注解@Super

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Super { }

然后我们定义一个User的子类SuperUser,并标注@Super注解

@Super
public class SuperUser extends User {
private String address;
// set / get / toString方法忽略
}

我们在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.snippets.spring.ioc.overview.dependency.domain.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
</bean>
<bean id="superUser" class="org.snippets.spring.ioc.overview.dependency.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>

如果通过User.class类型来找Bean,可能会找到SuperUser和User两个,但是加了Primary="true"这个配置,则只会找superUser这个Bean

接下来就是通过注解来找到Bean的代码

    private static void lookupByAnnotations(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory beanFactory1 = (ListableBeanFactory) beanFactory;
Map<String, User> users = (Map) beanFactory1.getBeansWithAnnotation(Super.class);
System.out.println(users);
}
}

打印结果:

{superUser=SuperUser{address='广州'} User{id=1, name='张三'}}

依赖注入

Spring IoC 依赖注入分为以下几种方式

  • 根据 Bean 名称注入

  • 根据 Bean 类型注入

    • 单个 Bean 对象
    • 集合 Bean 对象
  • 注入容器內建 Bean 对象

  • 注入非 Bean 对象

  • 注入类型

    • 实时注入
    • 延迟注入

增加UserRepository


public class UserRepository {
private Collection<User> users; // 自定义Bean
private BeanFactory beanFactory; // 内建非 Bean(依赖)
private ObjectFactory<ApplicationContext> objectFactory;
// 省略 set/get/toString方法
}

首先我们新建一个配置文件dependency-injection.xml

引入上一例中的dependency-lookup.xml,并增加一个Bean的配置, 并且配置手动注入这个Bean中属性信息

<?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.xml"/>
<bean id="userRepository"
class="org.snippets.spring.ioc.overview.dependency.repo.UserRepository"
>
<!-- 手动注入 -->
<property name="users">
<util:list>
<ref bean="user"/>
<ref bean="superUser"/>
</util:list>
</property>
</bean>
</beans>

测试

public class DependencyInjection {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
System.out.println(userRepository.getUsers());
}
}

可以打印出注入的user信息

也可以实现自动注入,我们以按类型自动注入为例,修改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.xml"/>
<bean id="userRepository"
class="org.snippets.spring.ioc.overview.dependency.repo.UserRepository"
autowire="byType"> <!-- 自动注入-->
</bean>
</beans>

增加autowire="byType" 即可

完整代码

Github

参考资料

小马哥讲Spring核心编程思想

最新文章

  1. 第四组 12月8号sprint会议
  2. Windows Phone 7之XNA游戏:重力感应
  3. Jquery幻灯片焦点图插件
  4. 微软的技术态度 -- 从其对于CRT的设计考虑说起
  5. 安装 PLSQL笔记
  6. haslayout引起的IE6 :hover失效
  7. action中实现对批量文件上传的封装
  8. vue setTimeout用法 jquery滚动到某一个div的底部
  9. Docker安装入门 -- 应用镜像
  10. (一〇二)静态库(.a)的打包
  11. Ubuntu15.04 + Matlab2014a + MatConvNet install and compile
  12. SqlServer执行Insert命令同时判断目标表中是否存在目标数据
  13. RxJava 详解——简洁的异步操作(二)
  14. 剑指Offer 22. 从上往下打印二叉树 (二叉树)
  15. thinkphp5.0 - Redis 实现秒杀
  16. ubuntu上安装ftp
  17. CSS 控制鼠标在元素停留的样式
  18. psql工具使用(二)
  19. 线程基础的一些理解(一)(java)
  20. Codeforces 1146E Hot is Cold

热门文章

  1. SpringSecurity注解的使用
  2. 2019牛客暑期多校训练营(第五场)G-subsequence 1
  3. 1152 Google Recruitment
  4. poj 3304 Segments(解题报告)
  5. 【uva 1471】Defense Lines(算法效率--使用数据结构+部分枚举+类贪心)
  6. Codeforces Round #570 (Div. 3) E. Subsequences (easy version) (搜索,STL)
  7. AtCoder Beginner Contest 170 D - Not Divisible (数学)
  8. 抓取QQ音乐歌单
  9. C# ArrayList和List的区别
  10. DCL 数据控制语言