7

有没有办法将 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)来避免演员表本身,但我仍然在两个地方有类型信息。

似乎 Spring 可以获取类信息 ( ApplicationContext.getType) 或通过从 bean 本身获取类型,但没有程序员干预无法自动转换类型。

4

6 回答 6

11

我同意 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");
于 2009-05-01T17:11:06.467 回答
4

答案是,如果可能的话,你根本不应该使用 ApplicationContext.getBean() ,并忍受你必须在引导代码中使用的一个地方。(通常,您永远不需要在应用程序的入口点之外使用 getBean()。)

此外,您所问的问题在 Java 语言中可能根本不可能。强制转换是一种编译时特性,结合了运行时检查。getBean() 的返回类型必须在编译时知道。即使 Spring 可以确定对象的类型,它也无法在运行时更改自己的方法签名。

另一件事是,即使这是可能的,该功能也不会那么有用。因为 Spring AOP 是使用动态代理实现的,所以您几乎总是希望 Spring 向您提供 bean 实现的接口的实例(可能是 AOP 代理),而不是实现类的实例。

于 2009-05-01T16:55:15.960 回答
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可以工作。)

于 2009-05-01T18:58:32.903 回答
1

没有类型化的主要原因getBean是 Spring(直到 2.5.x 版本)与 Java 1.4 的兼容性。Spring 3.0 将放弃它,从而提供类型化的getBean方法。

尽管如此,您应该避免直接查找 bean 并尽可能减少它的使用。

于 2009-05-02T17:37:50.077 回答
0

如果我使用 Spring 作为我的应用程序广泛使用的对象工厂会怎样。也就是说,与其编写一堆已经继承或包装已知 Java 类的类,我只是决定将所有这些移动到一个 xml 文件中以减少 Java 代码行。这将意味着很多行 xml,但我不需要制作我用 Spring 或 autowire 注入的骨架 Java 类。从而减少 Java 代码的行数。

出于这个原因,我仍然是 Spring 的新手,正如之前的帖子中所述,我使用了包含 getBeans() 的静态 Java 方法。

我曾与 Spring 合作过,但它对我来说仍然是新的,所以请原谅我的问题。

于 2009-09-21T14:07:25.747 回答
-1

“因为 Spring AOP 是使用动态代理实现的,所以您几乎总是希望 Spring 向您提供 bean 实现的接口的实例(可能是 AOP 代理),而不是实现类的实例”

所以没有办法使用 getBean() 获得动态代理,那么如果没有接口并且它是一个要执行的独立驱动程序类,那么最好的做法是什么?

于 2010-08-11T20:16:57.683 回答