【Spring Framework】spring管理自己new的对象
使用AutowireCapableBeanFactory手动注入
使用.newInstance();创建对象的话,如果其他对象都使用Spring Autowired,还需要手动创建所有依赖的Bean:
private @Autowired AutowireCapableBeanFactory beanFactory;
public void process() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
例如策略工厂中可以
private @Autowired AutowireCapableBeanFactory beanFactory;
/**
* 使用策略工厂获取具体策略实现
* @param code
* @return
*/
public PayStrategy getPayStrategy(String code) {
String className = PayEnumStrategy.getClassNameByCode(code);
try {
PayStrategy str = (PayStrategy) Class.forName(className).getDeclaredConstructor().newInstance();
beanFactory.autowireBean(str);
return str;
} catch (InstantiationException |
NoSuchMethodException |
ClassNotFoundException |
IllegalAccessException |
InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
但是这种方式只有对field注入方式才有用。
使用Map<String,?> 自动注入
先附上如下的代码:
public interface TalkService {
void talk(String content);
}
@Service(value = "withSisterTalkService")
public class WithSisterTalkService implements TalkService {
@Override
public void talk(String content) {
System.out.println(this.getClass().getName() + ":" + content);
}
}
@Service(value = "withGirlFriendTalkService")
public class WithGirlFriendTalkService implements TalkService {
@Override
public void talk(String content) {
System.out.println(this.getClass().getName() + ":" + content);
}
}
@Service
public class TalkServiceStrategyContext implements TalkService {
private Map<String, TalkService> strategyMap = new ConcurrentHashMap<>();
@Autowired
public TalkServiceStrategyContext(Map<String, TalkService> strategyMap) {
this.strategyMap.clear();
this.strategyMap.putAll(strategyMap);
}
@Override
public void talk(String content) {
}
}
注意,这里必须是Map<String, TalkService>类型!
@Autowired
private Map<String, TalkService> talkServiceMap;
@GetMapping(value = "doTest")
public String doTest() {
Set<String> strings = talkServiceMap.keySet();
for (String string : strings) {
System.out.println(string + ":" + talkServiceMap.get(string).toString());
}
return this.getClass().getName();
}
其访问测试controller后,打印的信息如下:
talkServiceStrategyContext:com.haiyang.onlinejava.complier.service.impl.TalkServiceStrategyContext@2f0b1419
withGirlFriendTalkService:com.haiyang.onlinejava.complier.service.impl.WithGirlFriendTalkService@1cf19a02
withSisterTalkService:com.haiyang.onlinejava.complier.service.impl.WithSisterTalkService@1ef3c76d
看了后感觉很奇怪,在上方只定义了一个map<String,TalkService>的map,居然它就能自动找到实现了TalkService的所有bean,并将service的beanName作为了key,感觉还是牛逼啊,spring的注解居然还能这样用。
然后简单看了下Autowired的源码,其javaDoc文档里也有说明:
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a constructor, field, setter method or config method as to be
* autowired by Spring's dependency injection facilities.
*
* <p>Only one constructor (at max) of any given bean class may carry this
* annotation, indicating the constructor to autowire when used as a Spring
* bean. Such a constructor does not have to be public.
*
* <p>Fields are injected right after construction of a bean, before any
* config methods are invoked. Such a config field does not have to be public.
*
* <p>Config methods may have an arbitrary name and any number of arguments;
* each of those arguments will be autowired with a matching bean in the
* Spring container. Bean property setter methods are effectively just
* a special case of such a general config method. Such config methods
* do not have to be public.
*
* <p>In the case of multiple argument methods, the 'required' parameter is
* applicable for all arguments.
*
* <p>In case of a {@link java.util.Collection} or {@link java.util.Map}
* dependency type, the container will autowire all beans matching the
* declared value type. In case of a Map, the keys must be declared as
* type String and will be resolved to the corresponding bean names.
*
* <p>Note that actual injection is performed through a
* {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} which in turn means that you <em>cannot</em>
* use {@code @Autowired} to inject references into
* {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} or
* {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessor}
* types. Please consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
* class (which, by default, checks for the presence of this annotation).
*
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
* @see AutowiredAnnotationBeanPostProcessor
* @see Qualifier
* @see Value
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
关注这句:
In case of a java.util.Collection or java.util.Map dependency type, the container will autowire all beans matching the declared value type. In case of a Map, the keys must be declared as type String and will be resolved to the corresponding bean names.
它大致是说Autowired当使用在Collection里时,会将所申明类的所有实现类都放在那个指定的Collection里;
如果Autowired和map使用的话呢,它将它bean的名称作为key,所有的bean作为value.
使用Set<?>自动注入
如果不想使用bean的名字作为map的Key的话,我们可以自定义寻址方式,自动注入时候使用Set<?>:
public interface Strategy {
void doStuff();
StrategyName getStrategyName();
}
public enum StrategyName {
StrategyA,
StrategyB,
StrategyC
}
@Component
public class StrategyA implements Strategy{
@Override
public void doStuff() {
//implement algorithm A here
}
@Override
public StrategyName getStrategyName() {
return StrategyName.StrategyA;
}
}
@Component
public class StrategyB implements Strategy{
@Override
public void doStuff() {
//implement algorithm B here
}
@Override
public StrategyName getStrategyName() {
return StrategyName.StrategyB;
}
}
@Component
public class StrategyC implements Strategy{
@Override
public void doStuff() {
}
@Override
public StrategyName getStrategyName() {
return StrategyName.StrategyC;
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
@Component
public class StrategyFactory {
private Map<StrategyName, Strategy> strategies;
@Autowired
public StrategyFactory(Set<Strategy> strategySet) {
createStrategy(strategySet);
}
public Strategy findStrategy(StrategyName strategyName) {
return strategies.get(strategyName);
}
private void createStrategy(Set<Strategy> strategySet) {
strategies = new HashMap<StrategyName, Strategy>();
strategySet.forEach(
strategy ->strategies.put(strategy.getStrategyName(), strategy));
}
}
Now we can inject StrategyFactory using @Autowired annotation. Here is the sample code using our StrategyFactory.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SomeService {
@Autowired
private StrategyFactory strategyFactory;
public void findSome(){
// Now get the strategy by passing the name
Strategy strategy = strategyFactory.findStrategy(StrategyName.StrategyA);
// you can now call the methods defined in strategy.
strategy.doStuff();
}
}
【Spring Framework】spring管理自己new的对象的更多相关文章
- Difference between BeanFactory and FactoryBean in Spring Framework (Spring BeanFactory与Factory区别)
参见原文:http://www.geekabyte.io/2014/11/difference-between-beanfactory-and.html geekAbyte Codes and Ran ...
- 1.Spring Framework 5.0 入门篇
1.为什么学习Spring? 随着对Java EE的不断接触和理解,你会发现Spring 在各个企业和项目中发挥着越来越重要的作用.掌握Spring 已成为我们IT行业生存必学的本领之一. Spri ...
- Spring Framework(框架)整体架构 变迁
Spring Framework(框架)整体架构 2018年04月24日 11:16:41 阅读数:1444 标签: Spring框架架构 更多 个人分类: Spring框架 版权声明:本文为博主 ...
- Spring Framework 官方文档学习(二)之IoC容器与bean lifecycle
到目前为止,已经看了一百页.再次感慨下,如果想使用Spring,那可以看视频或者找例子,但如果想深入理解Spring,最好还是看官方文档. 原计划是把一些基本接口的功能.层次以及彼此的关系罗列一下.同 ...
- Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转
小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...
- 框架应用:Spring framework (四) - 事务管理
事务控制 事务是什么?事务控制? 事务这个词最早是在数据库中进行应用,讲的用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位. 事务的管理是指一个事务的开启,内容添加, ...
- Spring Framework核心概念之Bean生命周期管理
目录 Spring Bean的生命周期 相关接口的分类 测试SpringBean生命周期的Demo程序 小结 Spring Bean的生命周期 Spring容器既Application或者WebApp ...
- 第四章 Spring.Net 如何管理您的类___对象、对象工厂和应用程序上下文
在前面一章我们介绍了依赖注入,控制反转的概念,以及自己动手搭建了一下Spring.Net的环境.通过这些操作,我们知道了Spring.Net 的核心是使用依赖注入或控制反转这种思想来管理业务对象,降低 ...
- 【Spring Framework】Spring入门教程(八)Spring的事务管理
事务是什么? 事务:指单个逻辑操作单元的集合. 在操作数据库时(增删改),如果同时操作多次数据,我们从业务希望,要么全部成功,要么全部失败.这种情况称为事务处理. 例如:A转账给B. 第一步,扣除A君 ...
- 第四章 Spring.Net 如何管理您的类___让对象了解自己的容器
我们在开发中,经常需要让对象了解自己所在的容器的信息,例如,有时我们需要让对象知道,对象所在容器的引用是什么,或者是对象在容器中的名称是什么 .Spring.Net 中提供了两个接口,我们使用这两个接 ...
随机推荐
- Oracle四大语言DDL DML DCL TCL
DDL(数据定义语言) creater 创建数据表 ceater table 表名 (); alter 修改表结构 添加字段:alter table 表名 add 列名 数据类型 null 删除字段: ...
- linux下go环境配置
环境申明: centos 7.4 1.go下载最新的版本(linux) 下载本地后rz到服务器,然后tar -zxvf go1.9.2.linux-amd64.tar.gz 解压出go文件放在 ...
- 字符编码和python文件操作
字符编码和文件操作 目录 字符编码和文件操作 1. 字符编码 1.1 什么是字符编码 1.2 字符编码的发展史 1.2.1 ASCII码 1.2.2 各国编码 1.2.3 Unicode 1.3 字符 ...
- 美团饿了么领取外卖优惠券微信小程序的开发及上线_怎样点外卖省钱_外卖小程序的开发及上线
都1202年了,估计没人不知道外卖了,那么就有两种人在思考两种问题: 普通人:怎么点外卖划算? 程序员:怎么通过外卖赚钱? 话不多说,为了让你们相信我有能力来讲这块内容,先给你们看一个很简单的小程序: ...
- [atARC096F]Sweet Alchemy
给定一棵有根树,记$f_{i}$表示$i$的父亲,每一个点有一个代价$c_{i}$ 给定常数$D$和$X$,再给每个点赋一个权值$v_{i}$($v_{i}\ge 0$),满足以下条件下最大化$\su ...
- [bzoj1109]堆积木
用f[i]表示前i个数,i必须被贡献的答案,考虑转移,枚举下一个被贡献的数j,那么j需要满足:1.$j<i$:2.$a[j]<a[i]$:3.$a[i]-(i-j+1)\le a[j]$, ...
- 【TcaplusDB知识库】如何部署TcaplusDB Local 版
[TcaplusDB知识库]部署TcaplusDB Local 版的准备操作 1. 版本介绍 TcaplusDB Local版,是为用户提供的一个满足本地开发调试的版本(基于Docker部署的可下载版 ...
- shell常用集锦
该文整理一些常用的shell用法,及语法,并非介绍如何使用 变量 变量可分为两类:环境变量ENV(全局)和局部变量. bash环境变量 变量名 含义 _= 上一条命令的最后一个参数 BASH_VERS ...
- Trie树(字典树,单词查找树)详解+题目
什么是字典树? 叫前缀树更容易理解 字典树的样子 Trie又被称为前缀树.字典树,所以当然是一棵树.上面这棵Trie树包含的字符串集合是{in, inn, int, tea, ten, to}.每个节 ...
- [源码解析] PyTorch 分布式 Autograd (2) ---- RPC基础
[源码解析] PyTorch 分布式 Autograd (2) ---- RPC基础 目录 [源码解析] PyTorch 分布式 Autograd (2) ---- RPC基础 0x00 摘要 0x0 ...