英文:
How to fail when bean annotated with javax.faces.bean.ViewScoped
问题
有没有一种方法可以检测到使用javax.faces.bean.ViewScoped
创建的@Named
CDI-Bean?我多次遇到过,IDE更喜欢这个注解而不是javax.faces.view.ViewScoped
。
当发现有一个使用javax.faces.bean.ViewScoped
注解的CDI-Bean时,有没有一种好的方法来中止应用程序的启动?
英文:
Is there a way of detecting @Named
CDI-Beans which are created with javax.faces.bean.ViewScoped
? It happened multiple times to me, that the IDE preferred this annotation to javax.faces.view.ViewScoped
.
Is there a good way to just abort the application startup when a javax.faces.bean.ViewScoped
annotated CDI-Bean is found?
答案1
得分: 4
是的!只要你有一个bean-discovery-mode="all"
,你可以使用CDI扩展来实现这一点。
这里是一个为你特定情况量身定制的启动示例:
package com.stackoverflow.q76653269;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
public class BadBeansDetector implements Extension {
<T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> type) {
Set<Class<?>> badBeans = new HashSet<>();
if (type.getAnnotatedType().getAnnotation(javax.faces.bean.ViewScoped.class) != null) {
badBeans.add(type.getAnnotatedType().getJavaClass());
}
if (!badBeans.isEmpty()) {
throw new DeploymentException("发现了错误的Bean!" + badBeans);
}
}
}
要使其运行,创建一个META-INF/services/javax.enterprise.inject.spi.Extension
文本文件,其唯一内容为:
com.stackoverflow.q76653269.BadBeansDetector
对于Maven WAR项目,此META-INF
文件夹必须位于src/main/resources
中(而不是src/main/webapp
)。
如果你的bean-discovery-mode="annotated"
,那么这将无法工作,但是错误的bean在首次注入时将无法使用,并且在任何你对其进行@Inject
时都会阻止部署并引发未满足依赖关系的异常,你也不需要提出这个问题。
当然,另一种选择是升级到JSF 2.3,其中此注解标记为@Deprecated
,并重新配置你的构建/编译器以在遇到已弃用的内容时失败。另一种选择是进一步迁移到Faces 4.0,其中已经移除了这个弃用的注解
英文:
> Is there a good way to just abort the application startup when a javax.faces.bean.ViewScoped
annotated CDI-Bean is found?
Yes! You can use a CDI extension for this as long as you've a bean-discovery-mode="all"
.
Here's a kickoff example tailored for your specific use case:
package com.stackoverflow.q76653269;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
public class BadBeansDetector implements Extension {
<T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> type) {
Set<Class<?>> badBeans = new HashSet<>();
if (type.getAnnotatedType().getAnnotation(javax.faces.bean.ViewScoped.class) != null) {
badBeans.add(type.getAnnotatedType().getJavaClass());
}
if (!badBeans.isEmpty()) {
throw new DeploymentException("Bad beans found! " + badBeans);
}
}
}
To get it to run, create a META-INF/services/javax.enterprise.inject.spi.Extension
text file with the sole content:
com.stackoverflow.q76653269.BadBeansDetector
In case of a Maven WAR project, this META-INF
folder must reside in src/main/resources
(and thus not src/main/webapp
).
In case you've bean-discovery-mode="annotated"
, then this won't work, but the bad bean would in first place not be injectable and already block deployment with an unsatisfied dependency exception anywhere you @Inject
it and you wouldn't need to ask this question.
The alternative is of course to upgrade to JSF 2.3 where this annotation is marked @Deprecated
and reconfigure your build/compiler to fail when a deprecated thing is encountered. Yet another alternative is to migrate further to Faces 4.0 where this deprecated annotation is long removed
答案2
得分: 4
我认为之前的答案已经不错了,但另一种在编译时捕获此问题的方法是使用Maven Enforcer插件:https://maven.apache.org/enforcer/maven-enforcer-plugin/usage.html
然后使用这个规则扩展来搜索被禁止的类使用:https://github.com/skuzzle/restrict-imports-enforcer-rule
在您的pom.xml中的总体更改将类似于:
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.3.0</version>
<dependencies>
<dependency>
<groupId>de.skuzzle.enforcer</groupId>
<artifactId>restrict-imports-enforcer-rule</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>check-viewscopedjsf-imports</id>
<phase>process-sources</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<RestrictImports>
<reason>Use CDI managed beans, not deprecated JSF APIs</reason>
<bannedImport>javax.faces.bean.**</bannedImport>
</RestrictImports>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
这种方法的优点是您可以在编译时捕获错误,而不是在运行时,因此根据您的用例,它可能会节省一些时间。不过,我认为这不会检查第三方库,而BalusC的解决方案会检查。所以,如果这在您的堆栈中是一个大问题,您可能可以同时运行这两个解决方案以获得全面的覆盖。
英文:
I think the previous answer is just fine, but another way to catch this at compile time would be to use the Maven Enforcer plugin: https://maven.apache.org/enforcer/maven-enforcer-plugin/usage.html
Then use this rule extensions that can search for banned class usages: https://github.com/skuzzle/restrict-imports-enforcer-rule
The total change in your pom.xml would be something like:
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.3.0</version>
<dependencies>
<dependency>
<groupId>de.skuzzle.enforcer</groupId>
<artifactId>restrict-imports-enforcer-rule</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>check-viewscopedjsf-imports</id>
<phase>process-sources</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<RestrictImports>
<reason>Use CDI managed beans, not deprecated JSF APIs</reason>
<bannedImport>javax.faces.bean.**</bannedImport>
</RestrictImports>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The advantage of this approach is you'll catch the error while compiling, instead of while running, so it may save you a bit of time depending on your use case. I don't think this will check third party libraries however, which BalusC's solution would do. So if this is a big problem in your stack, you could probably run both solutions for full coverage.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论