English 中文(简体)
What are the available options to retrieve Spring-managed beans in a Log4J Appender inside a Spring-managed web application?
原标题:

My current build lead has a great idea in theory - construct a custom Log4J appender that takes in Spring-managed beans and uses them to log errors to various other sources than just the standard log file. However, other than creating a singleton initialized at startup with the application context (code in just a moment), I can t seem to think of any other options of retrieving a Spring managed bean in a Log4J appender.

public class SpringSingleton implements ApplicationContextAware {
    private static ApplicationContext context;
    public SpringSingleton() {
        super();
    }
    public static ApplicationContext getContext() {
        return SpringSingleton.context;
    }
    public void setApplicationContext(ApplicationContext context) {
        if(SpringSingleton.context != null) {
            throw new IllegalStateException("Context is already set!");
        }
        SpringSingleton.context = context;
    }
}

Ideally, these properties could be set just like beans in Spring via dependency injection - the bean references will never change, no matter how many appenders are initialized. Any ideas?

最佳回答

You re going to have a boostrap problem since log4j has to be initialized before Spring. Whether you re using a custom configuration or Log4j s standard initializer, it has to be up before application context is.

Now, you could in theory make your custom appenders "lazily" initialize themselves (either via approach you ve suggested above or by making appenders themselves "semi" singletons - e.g. appender class has a static instance field which gets populated by afterPropertiesSet() method; that way you can create appender itself as bean within Spring) but it seems somewhat messy and inconsistent.

Another approach is to dynamically reconfigure Log4j once Spring context is initialized; e.g. write a listener to catch a ContextStartedEvent, obtain all beans of type Appender from the context and add them to Log4j configuration. This will also allow you to create your appenders as beans but avoid singleton mess somewhat.

问题回答

Bit late, but I hope that this can help someone else. I ve documented a solution to this issue in the answer i ve provided in the following link:

log4j - Accessing spring bean from logging appender class





相关问题
array dependency injection in spring?

is there a way to use dependency injection to inject all available implementations of a specific interface in spring? This is kind of the same thing as asked here for .NET. Though my aim is to use @...

Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Grails Packaging and Naming Conventions

Packaging Controllers, Services,etc. i.e. - com.company.controllers - com.company.services Is this a good practice or should be avoided by all means?? Another worth mentioning problem I encountered ...

How can I determine Objects in application context?

I am trying to write a portlet for Liferay (using Tomcat and Spring) and need to use a database via Persistence API/Hibernate. I am using some configuration XMLs (applicationContext.xml, etc.) and ...

How to prevent JPA from rolling back transaction?

Methods invoked: 1. Struts Action 2. Service class method (annotated by @Transactional) 3. Xfire webservice call Everything including struts (DelegatingActionProxy) and transactions is configured ...

热门标签