【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 中提供了两个接口,我们使用这两个接 ...
随机推荐
- ofd文件电子签章实现方法
前言 文档处理一般经过三个环节:流.版.签:流式软件负责编辑,如:office.wps等.版式软件负责文档定型,保证显示样式不跑偏:版式文件格式有两种:pdf.ofd.签章软件负责对版式文档签章.签章 ...
- 百度ueditor编辑器注入漏洞修补查杀程序
百度ueditor编辑器注入查杀程序,用于对百度ueditor的漏洞补丁进行查杀,使用时需要保证本地正确部署了.net 4.0服务. 百度ueditor编辑器是目前网上比较流行的一个网站编辑器,但由于 ...
- 最大连续子数组和--dp
最大连续子数组和 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整数均为负数时定义子段 ...
- [hdu6600]Just Skip The Problem
1.直接令x=0,为了判断这一信息,对于所有含有多个1的yi,必然是无用的,答案至少为n且不能含有多位1的y2.令yi=2^(i-1),由此发现一定可以得到x每一位的答案,即答案最多为n.因此,发现方 ...
- 直接插入100w数据报错
### Cause: com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (77,600 ...
- k8s statefulset controller源码分析
statefulset controller分析 statefulset简介 statefulset是Kubernetes提供的管理有状态应用的对象,而deployment用于管理无状态应用. 有状态 ...
- MySQL的B+树索引和hash索引的区别
简述一下索引: 索引是数据库表中一列或多列的值进行排序的一种数据结构:索引分为聚集索引和非聚集索引,聚集索引查询类似书的目录,快速定位查找的数据,非聚集索引查询一般需要再次回表查询一次,如果不使用索引 ...
- Linux—软件包管理器yum安装详解
yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器. 基於RPM包管理,能够从指定的服务器自动下载RPM包 ...
- No.1 R语言在生物信息中的应用——序列读取及格式化输出
目的:读入序列文件(fasta格式),返回一个数据框,内容包括--存储ID.注释行(anno).长度(len).序列内容(content) 一.问题思考: 1. 如何识别注释行和序列内容行 2. 如何 ...
- IO流的字节输入输出流(InputStream,OutputStream)
字节输出流与文件字节输出流 文件存储原理和记事本打开文件原理 OutputStream及FileOutputStream import java.io.FileOutputStream; import ...