有没有办法将Spring bean自动转换为应用程序上下文XML中定义的类?我想避免将bean的类型信息放在2个位置....在xml配置文件中,也在代码中作为强制转换。
例如,给定此配置文件
<bean id="bean-name" class="SimpleSpringBean" scope="prototype">
<property name="myValue" value="simple value"></property>
</bean>
我是否可以以避免直接将返回类型转换为ApplicationContext.getBean("bean-name")
的方式调用SimpleStringBean
。我知道我也可以调用ApplicationContext.getBean("bean-name", SimpleSpringBean.class)
来避免演员本身,但我仍然有2个地方的类型信息。
看起来Spring可以获取类信息(ApplicationContext.getType
)或者从bean本身获取类型,但没有办法在没有程序员干预的情况下自动转换类型。
答案 0 :(得分:10)
我同意Sii,你应该避免尽可能多地调用getBean。只需将bean连接到依赖于它们的类。
但是,如果您有一个包含应用程序上下文的类,则可以提供如下所示的包装器通用方法:
class MyContextHolder{
ApplicationContext appContext;
......
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName)
{
return (T)appContext.getBean(beanName);
}
}
然后你可以不用强制转换来调用它
MyClass mc = MyContextHolder.getBean("myClassBean");
答案 1 :(得分:4)
答案是,如果可能的话,您根本不应该使用ApplicationContext.getBean(),并且必须在引导代码中使用一个地方。 (通常,您永远不需要在应用程序的入口点之外使用getBean()。)
此外,您所要求的内容在Java语言中根本不可能。 Casting是一个编译时功能,结合运行时检查。 getBean()的返回类型必须在编译时才能知道。即使Spring可以确定对象的类型,它也不能在运行时更改自己的方法签名。
另一件事是,即使这是可能的,该功能也不会那么有用。因为Spring AOP是使用动态代理实现的,所以你几乎总是希望Spring为你提供bean实现的接口实例(可以是AOP代理),而不是实现类。
答案 2 :(得分:1)
我还使用的另一种方法是使用以下方法自动装配引导类:
public class Main {
@Autowired FooFacade foo;
@Autowired BarFacade bar;
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
Object main = bf.createBean(Main.class,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
false);
((Main) main).run();
}
private void run() {
foo.doBootstrapStuff();
bar.doMoreBootstrapStuff();
}
}
(代码是从内存完成的。如果你将Spring上下文配置为处理布线注释,那么只有在foo
和bar
设置setter时才有效。)
答案 3 :(得分:1)
getBean
无类型化的主要原因是Spring(最高版本2.5.x)与Java 1.4的兼容性。 Spring 3.0将丢弃它,从而提供类型化的getBean
方法。
尽管如此,您应该避免直接查找bean并尽可能减少其使用量。
答案 4 :(得分:0)
如果我将Spring用作我的应用程序广泛使用的对象工厂,该怎么办? 也就是说,而不是写一堆已经继承或包裹的类 已知的Java类我只是决定将所有这些转移到xml文件中以减少 Java代码行。这将意味着许多行xml,但我不需要 我用Spring或autowire注入的框架Java类。从而制作线条 Java代码少。
出于这个原因,我仍然是Spring的新手,我刚才在前面说过 posts使用了围绕getBeans()的静态Java方法。
我曾与Spring合作,但对我来说还是新的,请原谅我的问题。
答案 5 :(得分:-1)
“因为Spring AOP是使用动态代理实现的,所以你几乎总是希望Spring为你提供一个bean实现的接口实例(可能是AOP代理),而不是实现类”
所以没有办法使用getBean()获取动态代理,那么如果没有接口并且它是一个独立的驱动程序类,那么最佳实践是什么?