java JSF 如何找到用@ManagedBean 注释的 bean?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3717376/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:08:41  来源:igfitidea点击:

How does JSF find beans annotated with @ManagedBean?

javaannotationsjsf-2managed-bean

提问by Iravanchi

As far as I know, for using @Annotations (or [Attributes] in C#) you have to have a reference to the class metadata, so that you can ask if the class is annotated (attributed) or not.

据我所知,要使用@Annotations(或 C# 中的 [Attributes]),您必须引用类元数据,以便您可以询问该类是否被注释(归因)。

My question is how does JSF implementation find all classes annotated with @ManagedBean? Does it scan all of the classes in the class path? Or is there a way to actually "query" the JVM for the annotated classes?

我的问题是 JSF 实现如何找到所有用 @ManagedBean 注释的类?它是否扫描类路径中的所有类?或者有没有办法实际“查询”带有注释的类的JVM?

I'm asking this because when I put my annotated backing beans in my web project directly, there's no problem. But the beans that I define in the JAR files (to be reusable across projects) are not registered. Is there something that I have to tell MyFaces to direct it which JAR files to look at?

我问这个是因为当我将带注释的支持 bean 直接放在我的 web 项目中时,没有问题。但是我在 JAR 文件中定义的 bean(可跨项目重用)没有注册。有什么我必须告诉 MyFaces 来指导它查看哪些 JAR 文件的吗?

Also, using annotations introduce many nice patterns of programming. I want to know if I can find all annotated classes somehow...

此外,使用注释引入了许多不错的编程模式。我想知道我是否能以某种方式找到所有带注释的类......

回答by BalusC

My question is how does JSF implementation find all classes annotated with @ManagedBean? Does it scan all of the classes in the class path? Or is there a way to actually "query" the JVM for the annotated classes?

我的问题是 JSF 实现如何找到所有用 @ManagedBean 注释的类?它是否扫描类路径中的所有类?或者有没有办法实际“查询”带有注释的类的JVM?

Start by peeking around in com.sun.faces.application.annotation.AnnotationManagerin Mojarrasources. Note that this is not part of the API, but implementation-specific.

在偷看周围开始com.sun.faces.application.annotation.AnnotationManager钻嘴鱼科源。请注意,这不是 API 的一部分,而是特定于实现的。

If you intend to use such tools for your own projects, I recommend using Reflectionsfor this instead of homegrowing it.

如果您打算在自己的项目中使用此类工具,我建议为此使用Reflections,而不是自行开发。

Set<Class<?>> classes = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

In a Java EE environment, better yet is to use CDI instead.

在 Java EE 环境中,最好改用 CDI。



I'm asking this because when I put my annotated backing beans in my web project directly, there's no problem. But the beans that I define in the JAR files (to be reusable across projects) are not registered. Is there something that I have to tell MyFaces to direct it which JAR files to look at?

我问这个是因为当我将带注释的支持 bean 直接放在我的 web 项目中时,没有问题。但是我在 JAR 文件中定义的 bean(可跨项目重用)没有注册。有什么我必须告诉 MyFaces 来指导它查看哪些 JAR 文件的吗?

To have JSF to load any annotated managed beans from a JAR file, you have to put a /META-INF/faces-config.xmlfile in the JAR file. Just a JSF 2.0 compatible <faces-config>declaration is sufficient to get the JSF scan the JAR file for any interesting annotated classes. If the /META-INF/faces-config.xmlfile is not present in the JAR file, then JSF won't scan the JAR file to improve loading performance.

要让 JSF 从 JAR 文件加载任何带注释的托管 bean,您必须/META-INF/faces-config.xml在 JAR 文件中放置一个文件。只需一个 JSF 2.0 兼容<faces-config>声明就足以让 JSF 扫描 JAR 文件以查找任何有趣的带注释的类。如果/META-INF/faces-config.xmlJAR 文件中不存在该文件,则 JSF 将不会扫描 JAR 文件以提高加载性能。

Here's how a minimum JSF 2.0 compatible faces-config.xmlfile look like:

下面是最小 JSF 2.0 兼容faces-config.xml文件的样子:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
</faces-config>

Store it in the META-INFfolder of the JAR.

将其存储在META-INFJAR 文件夹中。

This is by the way described in chapter 11.4.2 of JSF 2.0 specification.

这是JSF 2.0 规范第 11.4.2 章中描述的方式。

11.4.2 Application Startup Behavior

...

This algorithm provides considerable flexibility for developers that are assembling the components of a JSF-based web application. For example, an application might include one or more custom UIComponent implementations, along with associated Renderers, so it can declare them in an application resource named “/WEB-INF/faces-config.xml” with no need to programmatically register them with Application instance. In addition, the application might choose to include a component library (packaged as a JAR file) that includes a “META-INF/faces-config.xml” resource.The existence of this resource causes components, renderers, and other JSF implementation classes that are stored in this library JAR file to be automatically registered, with no action required by the application.

11.4.2 应用程序启动行为

...

该算法为组装基于 JSF 的 Web 应用程序组件的开发人员提供了相当大的灵活性。例如,一个应用程序可能包含一个或多个自定义 UIComponent 实现以及关联的渲染器,因此它可以在名为“/WEB-INF/faces-config.xml”的应用程序资源中声明它们,而无需以编程方式将它们注册到 Application实例。此外,应用程序可能会选择包含一个包含“META-INF/faces-config.xml”资源的组件库(打包为 JAR 文件)。此资源的存在会导致存储在此库 JAR 文件中的组件、渲染器和其他 JSF 实现类自动注册,应用程序无需执行任何操作。

See also:

也可以看看:

回答by Vivien Barousse

Actually, the container scans all classes within the current WAR file. Scanning all the classpath would be very long and costly.

实际上,容器会扫描当前 WAR 文件中的所有类。扫描所有的类路径将非常耗时且成本高昂。

That's why you can put your annotated managed beans within the WAR file, and not in a JAR file.

这就是为什么您可以将带注释的托管 bean 放在 WAR 文件中,而不是放在 JAR 文件中的原因。

If you really need to put your classes in a JAR file in the classpath, you can use the faces-config.xmlfile to tell JSF which classes are managed bean.

如果您确实需要将您的类放在类路径中的 JAR 文件中,您可以使用该faces-config.xml文件告诉 JSF 哪些类是托管 bean。