- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想为我当前的堆栈创建一个 LoggingInterceptor:
这是标记要拦截的方法或类型的注释。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface Logging {
@Nonbinding
Level value() default Level.TRACE;
public enum Level {
NONE, ALL, TRACE, DEBUG, INFO, WARN, ERROR;
}
}
这是拦截器逻辑:
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@Logging
public class LoggingInterceptor {
@AroundInvoke
public Object interceptBusiness(final InvocationContext invocationContext) throws Exception {
Logger log = LoggerFactory.getLogger(invocationContext.getMethod().getDeclaringClass().getName());
log.trace("LOG start of method");
Object result = invocationContext.proceed();
log.trace("LOG end of method");
return result;
}
}
简化的 Bean:
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.inject.Inject;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
@Logging(Level.DEBUG)
public class ListController implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
EntityService entityService;
private List<Entity> entityList;
public List<Entity> getEntityList() {
return this.entityList;
}
public void setEntityList(final List<Entity> entityList) {
this.entityList= entityList;
}
public String doSomething(){
List<Entity> entityList = new ArrayList<>();
this.setEntityList(entityList);
return "";
}
@PostConstruct
public void setUp() {
this.setEntityList(this.entityService.findAll());
}
}
如果在运行时调用,我的业务方法拦截器就像一个魅力,例如在 jsf View 中按下一个按钮时调用 doSomething()
方法。两者都是doSomething()
和 setEntityList()
方法将被记录。
但是在 @PostConstruct
中调用的所有方法方法根本没有记录。这意味着setEntityList()
在 @PostConstruct
中调用时不会记录方法方法。
我能做些什么来获取从 @PostConstruct
调用的方法吗?要记录的方法。我希望得到一些帮助。提前致谢。
根据 HRgiger 的回答进行更新:
我还尝试了 @PostConstruct
方法在我的拦截器逻辑中,但使用此方法我只能记录 @PostConstruct
的调用本身,而是 @PostConstruct
中调用的方法方法未记录,这仍然是我的主要问题。
@PostConstruct
public void interceptLifecycle(final InvocationContext invocationContext) throws Exception {
Logger log = LoggerFactory.getLogger(invocationContext.getTarget().getClass().getSimpleName());
log.info("LOG start of POSTCONSTRUCT");
invocationContext.proceed();
log.info("LOG end of POSTCONSTRUCT");
}
最佳答案
这是预期的行为。只有从 bean 外部对 bean 方法的调用才会被拦截,而不会从 bean 内部对其自身方法的调用被拦截。
来自weld/CDI 1.0.0 specification
A business method interceptor applies to invocations of methods of the bean by clients of the bean.
A lifecycle callback interceptor applies to invocations of lifecycle callbacks by the container.
这意味着您所描述的行为完全是有意为之。 @AroundInvoke
带注释的业务方法拦截器仅拦截从 bean 外部对 bean 调用的“正常”方法。这也意味着如果您的 bean 有方法 methodA()
和methodB()
,和methodA
来电 methodB
,当 methodA
仅从外部调用methodA
被记录,而不是 methodB
的调用.
假设您有以下内容:
@Named
@ViewScoped
@Logging(Level.DEBUG)
public class SimpleBean {
public void methodA() {
methodB();
}
public void methodB() {
// do something
}
}
在其他一些类中,您注入(inject)这个 bean,实际上是向该 bean 注入(inject)代理:
@Inject
private SimpleBean simpleBeanProxy;
当您调用simpleBeanProxy.methodA();
时,即methodA
调用被拦截,但 methodB
的调用未被拦截从内部methodA
。当您调用simpleBeanProxy.methodB();
时,调用methodB
被拦截。
生命周期回调也会发生类似的情况,拦截器拦截从外部(容器)对生命周期方法的调用,但不会拦截从该 postconstruct 方法内调用的同一 bean 上的任何方法。
这都是因为这些拦截器所做的拦截是由代理处理的。如果“从外部”调用 bean 上的方法,则实际上是在代理上调用该方法,并且代理确保在对实际 bean 对象执行实际方法调用之前调用任何已注册的拦截器。
但是,一旦您进入实际 bean 的“内部”方法并且从同一 bean 调用任何其他方法,您就不会使用代理(而是直接在同一对象上调用方法),因此不会发生拦截.
关于java - CDI 日志拦截器在 @PostConstruct 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49025452/
我对下面代码的结果有点困惑。 父 Controller : @Controller public abstract class ParentController{ @PostConstruct pub
我有这样的设置: Bean类: private final Map configCache = new HashMap<>(); @PostConstruct private void fillCac
这似乎不正确。我正在清理代码,只是注意到了这一点。每个ajax请求都会触发我的@PostConstruct bean的构造函数和@ViewScoped。即使是简单的数据库分页也会触发它。 我under
根据answer of BalusC ,我用过 FacesContext.getCurrentInstance().getExternalContext().redirect(url); 在我的 @P
我正在使用 Spring 开发一个 Java 小型应用程序,所以我有这个服务: public class AccountService implements UserDetailsService {
问题:entityManager.unwrap(SessionImplementor.class) 导致没有可用的事务实体管理器异常。 代码: @Component public class Hibe
我想使用 @PostConstruct 在我的 web 应用程序中初始化一个 bean,但我无法让它工作。 我已经在新项目中重新创建了该问题,但仍然无法正常工作。 我在这里遗漏了一些明显的东西吗?据我
我在 Java SE 应用程序中使用 CDI (Weld)。我制作了一个 Bean,我们称之为 BeanA。 public class BeanA { @PostConstruct p
在托管 bean 中,@PostConstruct 在常规 Java 对象构造函数之后调用。 为什么我要使用 @PostConstruct 来初始化 bean,而不是常规构造函数本身? 最佳答案 因为
我有 spring bean 类 RedisRepo在里面我正在使用@PostConstruct初始化我的数据库连接: @PostConstruct public void init() {
我使用了当前版本的 Eclipse 和 Java。我尝试将 RCP 应用程序从 Java 8 迁移到 Java 11。我的应用程序可以运行,但现在遇到功能问题,因为我必须从代码中删除 @PostC
由于我是 Java EE 7 的新手,所以我创建了一个项目以供学习之用。我创建了一个具有 Request 范围的 CDI bean,如下所示(它只是实现了 Serializable,因为我已经尝试将它
我有一个计划任务,每晚汇总数据。每当我启动应用程序时该任务就会运行,并且我想在应用程序上运行 jUnit 测试时停止它运行。 @Scheduled(cron = "0 0 0 1 * ?") publ
这个问题已经有答案了: How to get access to javax.annotation.Resource at run time in Java 9 (2 个回答) Java 9 migr
我正在 JBoss 上试验 EJB3,开发无状态 bean。基本上一旦部署了模块,我就需要执行一些与加载应用程序设置相关的操作。为此,我将一个方法注释为@PostConstruct,据我所知,API
假设我们有以下类 public abstract class AbstractFoo { @PostConstruct private void doIt() { //
我的 JEE 应用程序中有 2 个单例,我想在启动时对其进行初始化。像这样: @Singleton @Startup public class ServiceB { @EJB priv
我正在编写 JAX-RS 库(不是应用程序)。 我有: abstract class A { @PostConstruct private void constructed_a() {
假设我在 Spring @Configuration 中有这个依赖: @Bean public SomeClass someClass(SomeClass1 someClass1, SomeClass
我将 JSF 2.0 与 GlassFish 3.0 结合使用。 我有以下托管 Bean: @ManagedBean @RequestScoped public class OverviewContr
我是一名优秀的程序员,十分优秀!