该怎么用使用spring的注入来实现这个需求?盆友们

lihuayang 发布于 2016/11/23 15:43
阅读 357
收藏 0

描述:
需要将这个类交个spring容器来管理,该怎么实现?

需求1:全局单例
需求2:成员变量为map,需要初始化
需求3:不想对外暴露构造方法 && 不想对外暴露set方法

小生没有用过spring,查了下spring的注入,必须提供构造方法或者是set方法。其实疑问就在如何在类封装完好情况下,让spring管理我们的类。是否能实现?谢谢大家。

运行环境:
Spring4.0

没有用spring之前的类实现截图如下:

加载中
0
skhuhu
skhuhu
都static 了···干嘛给spring管理···
lihuayang
lihuayang
回复 @skhuhu :这个我倒是知道,还是谢谢你了
skhuhu
skhuhu
回复 @李华洋 : 要spring管理也行 别static``因为spring也是能保证单利的
lihuayang
lihuayang
也就是说这种情况用spring比较麻烦
0
亭舸翁
亭舸翁
要做的话,可以bean实现InitializingBean接口,在afterPropertiesSet里做初始化
lihuayang
lihuayang
好像挺麻烦的样子,看来这种情况不适合用spring
0
lock_free
lock_free
参考 BeanDefinitionRegistryPostProcessor,
beanFactory.registerSingleton("hhhh", new hhhh());

可以采用visitor模式
0
jianglibo
jianglibo

谈几点粗浅的看法。

1、名称是MessageDecoderPool,看起来是一个池,实际上不过是引用的保存地而已,不妨叫做MessageDecoderHolder。

2、Spring ioc没什么魔法,不知你为何需要将它变成spring管理。如果你想在增加新的decoder的时候不需要修改MessageDecoderPool的代码,而是采用自动发现,那么归spring管理还是有点意义的。比如下面的假代码(直接在这里书写可能会有语法错误):

@Target({ java.lang.annotation.ElementType.TYPE })
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Mdecoder {
	String name(); //as key
}

@Mdecoder("lmd")
public class LoginMessageDecoder implements MessageDecoder{

}

// every time you create a new decoder, it should be added to automaticlly. There is no need to change this file.
@Component
public class MessageDecoderPool {
    private Map<String, MessageDocoder> hodler = Maps.newHashMap();
   
    @PostConstruct
    public void ps() {
       Map<String, Object> dcs = applicationContext.getBeansWithAnnotation(Mdecoder.class);
     des.forEach((k,v) -> {
        Mdecoder ma = v.getClass().getAnnotationsByType(Mdecoder.class);
     holder.put(ma.name(), v);
     });
    }
}



0
lihuayang
lihuayang

引用来自“jianglibo”的评论

谈几点粗浅的看法。

1、名称是MessageDecoderPool,看起来是一个池,实际上不过是引用的保存地而已,不妨叫做MessageDecoderHolder。

2、Spring ioc没什么魔法,不知你为何需要将它变成spring管理。如果你想在增加新的decoder的时候不需要修改MessageDecoderPool的代码,而是采用自动发现,那么归spring管理还是有点意义的。比如下面的假代码(直接在这里书写可能会有语法错误):

@Target({ java.lang.annotation.ElementType.TYPE })
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Mdecoder {
	String name(); //as key
}

@Mdecoder("lmd")
public class LoginMessageDecoder implements MessageDecoder{

}

// every time you create a new decoder, it should be added to automaticlly. There is no need to change this file.
@Component
public class MessageDecoderPool {
    private Map<String, MessageDocoder> hodler = Maps.newHashMap();
   
    @PostConstruct
    public void ps() {
       Map<String, Object> dcs = applicationContext.getBeansWithAnnotation(Mdecoder.class);
     des.forEach((k,v) -> {
        Mdecoder ma = v.getClass().getAnnotationsByType(Mdecoder.class);
     holder.put(ma.name(), v);
     });
    }
}



首先,还是得谢谢你。
1. 关于pool是这样子,其实在我看来这就是一个池,哈哈,我不知道这样子命名对不对,看来我需好好的看看开源的池化技术。学学命名。至于你说的"不过是引用保存地而已",这句话我还是有点疑问,不保存地址,保存什么?
2. 再就是用ioc。之所以要这么做,其实也是一种尝试,并不知道ioc真正适用的地方。spring并没有什么魔法,是的是的。这种情况可能是不适合让spring来发挥。我还是老老实实的用原来的做法。
0
小石头过河
小石头过河

就你提出的这3个要求而已,1. spring本身默认就是单利模式; 2.map成员的初始化 如果像你代码中一样些死的话,不用spring注入的(猜测你理解成注入这个对象本身了)。spring的构造方法或者是set方法是注入动态对象,一般是借口对象 为了解耦。

所以一个基本的spring Bean就可以完成你的要求。

@Component
public class MessageDecoderPool {

	private MessageDecoderPool(){}
	private static final Map<String,String> map = new HashMap<>();
	static {
		map.put("0001", "T1");
		map.put("0002", "T2");
	}
	public String getDecoder(String key){
		return map.get(key);
	}
	
}



返回顶部
顶部