java 自动铸造 Spring Beans
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/812178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Auto-cast Spring Beans
提问by Vinnie
Is there a way to auto-cast Spring beans to the class defined in the application context XML? I'd like to avoid putting type information about the beans in 2 places.... in the xml configuration file and also in the code as a cast.
有没有办法将 Spring bean 自动转换为应用程序上下文 XML 中定义的类?我想避免将关于 bean 的类型信息放在 2 个地方......在 xml 配置文件和代码中作为演员表。
For instance, given this config file
例如,给定这个配置文件
<bean id="bean-name" class="SimpleSpringBean" scope="prototype">
<property name="myValue" value="simple value"></property>
</bean>
Can I call ApplicationContext.getBean("bean-name")in such a way as to avoid directly casting the return type to SimpleStringBean. I know I can also call ApplicationContext.getBean("bean-name", SimpleSpringBean.class)to avoid the cast itself, but I still have the type info in 2 places.
我可以ApplicationContext.getBean("bean-name")以一种避免直接将返回类型强制转换为SimpleStringBean. 我知道我也可以打电话ApplicationContext.getBean("bean-name", SimpleSpringBean.class)来避免演员表本身,但我仍然在 2 个地方有类型信息。
It seems that Spring can get the class info (ApplicationContext.getType) or by getting the type from the bean itself, but no way to automatically cast the type without programmer intervention.
似乎 Spring 可以获取类信息 ( ApplicationContext.getType) 或通过从 bean 本身获取类型,但没有办法在没有程序员干预的情况下自动转换类型。
回答by LiorH
I agree with Sii, you should avoid calling getBean as much as you can. Just wire your beans to classes that depends on them.
我同意 Sii,您应该尽可能避免调用 getBean。只需将您的 bean 连接到依赖它们的类。
Still, if you have a single class that holds the application context, you can provide a wrapper generic method like the following:
尽管如此,如果您有一个包含应用程序上下文的类,您可以提供一个包装器通用方法,如下所示:
class MyContextHolder{
ApplicationContext appContext;
......
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName)
{
return (T)appContext.getBean(beanName);
}
}
Then you can call it without casting
然后你可以在不强制转换的情况下调用它
MyClass mc = MyContextHolder.getBean("myClassBean");
回答by millimoose
The answer is you shouldn't be using ApplicationContext.getBean() at all if it's possible, and bear with the one place you have to in the bootstrap code. (Generally, you should never need to use getBean() outside of your application's entry points.)
答案是,如果可能的话,您根本不应该使用 ApplicationContext.getBean(),并在引导程序代码中留出一个位置。(通常,您永远不需要在应用程序入口点之外使用 getBean()。)
Also, what you're asking is likely impossible in the Java language at all. Casting is a compile-time feature, combined with a runtime check. The return type of getBean() simply must be known at compile time. Even if Spring can determine the type of an object, it can't change its own method signatures at runtime.
此外,您所问的问题在 Java 语言中可能根本不可能。Casting 是一个编译时特性,结合了运行时检查。getBean() 的返回类型必须在编译时知道。即使 Spring 可以确定对象的类型,它也无法在运行时更改自己的方法签名。
Another thing is that even if this were possible, the feature wouldn't be all that useful. Because Spring AOP is implemented using dynamic proxies, you nearly always want Spring to hand you an instance of an interface the bean implements (which could be an AOP proxy), not of the implementation class.
另一件事是,即使这是可能的,该功能也不会那么有用。因为 Spring AOP 是使用动态代理实现的,所以您几乎总是希望 Spring 向您提供 bean 实现的接口实例(可以是 AOP 代理),而不是实现类的实例。
回答by millimoose
Another approach I also use is autowiring the bootstrapping class using:
我还使用的另一种方法是使用以下方法自动装配引导类:
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();
}
}
(Code done from memory. Might only work if you have the Spring context configured to process wiring annotations, in that case making setters for fooand barshould work.)
(代码从内存中完成。可能只有在您将 Spring 上下文配置为处理连线注释时才可能工作,在这种情况下,为foo并且bar应该工作的设置器。)
回答by Oliver Drotbohm
The main reason for getBeanbeing untyped is the compatibility of Spring (up to version 2.5.x) with Java 1.4. Spring 3.0 will drop that and thus offer typed getBeanmethod then.
getBean无类型化的主要原因是 Spring(最高版本 2.5.x)与 Java 1.4 的兼容性。Spring 3.0 将放弃它并因此提供类型化getBean方法。
Nevertheless you should avoid looking up beans directly and minimize its usage as far as possible.
尽管如此,您应该避免直接查找 bean 并尽可能减少其使用。
回答by Oliver Drotbohm
What if I use Spring as an object factory that my application uses extensively. That is, instead of writing a bunch of classes that already inherit or wrap around known Java classes I just decide to move all that into an xml file to cut down on lines of Java code. This will mean many lines of xml but I won't need to make skeleton Java classes which I inject with Spring or autowire. Thus making the lines of Java code less.
如果我使用 Spring 作为我的应用程序广泛使用的对象工厂怎么办。也就是说,我没有编写一堆已经继承或环绕已知 Java 类的类,而是决定将所有这些都移动到一个 xml 文件中以减少 Java 代码行。这将意味着多行 xml,但我不需要制作用 Spring 或 autowire 注入的骨架 Java 类。从而减少了 Java 代码的行数。
For this reason and still as I am new to Spring I have just as stated in previous posts used static Java methods which wrap around the getBeans().
出于这个原因,而且我仍然是 Spring 的新手,正如之前的文章中所述,我使用了围绕 getBeans() 的静态 Java 方法。
I have worked with Spring but it is still new to me so forgive my question.
我曾与 Spring 合作过,但它对我来说仍然是新的,所以请原谅我的问题。
回答by user251779
"Because Spring AOP is implemented using dynamic proxies, you nearly always want Spring to hand you an instance of an interface the bean implements (which could be an AOP proxy), not of the implementation class"
“因为 Spring AOP 是使用动态代理实现的,您几乎总是希望 Spring 向您提供 bean 实现的接口实例(可能是 AOP 代理),而不是实现类的实例”
So there is no way to get a dynamic proxy using getBean(), then whats the best practice if there are no interfaces and its a stand alone driver class to be executed?
所以没有办法使用 getBean() 获得动态代理,那么如果没有接口并且它是要执行的独立驱动程序类,最佳实践是什么?

