如何通过一定的依赖注入限制对象创建?

时间:2011-03-08 07:14:17

标签: java

我正在创建内部使用LOG4j的自定义日志记录功能类。那些想要使用日志记录功能的类,它传递了class.i的名称想要知道如何在不将类名传递给它的情况下限制对象创建。我试过但是我不确定它是否是正确的方法我做了吗?


public class LoggerObject 
{
    private Logger logger;
    private static LoggerObject loggerobj;
    private ConstantDataManager constantdatamanger;

    //Default Log4J_FILE Path
    private LoggerObject(String className)
    {
      try
      {
        DOMConfigurator.configure(this.getClass().getClassLoader().getResource(constantdatamanger.LOG4J_FILE));
        logger =Logger.getLogger(className);
       }
      catch(Exception ex)
      {
          System.out.println("DOMConfigurator could not find file"+ex.getMessage());
      }
    }

     public static LoggerObject getLogger(String className)
        {
            if (loggerobj==null)
            {
             loggerobj = new LoggerObject(className);
            }
             return loggerobj;
        }


    public void info(Object message)
    {
        logger.info(message);
    }

    public void info(Object message, Throwable t) {
        logger.info(message, t);
    }

    public void error(Object message) {
         logger.error(message);
    }

    public void error(Object message, Throwable t) {
       logger.error(message,t);
    }

    public void debug(Object message) {
       logger.debug(message);
    }

    public void debug(Object message, Throwable t) {
        logger.debug(message,t);
    }

    public void warn(Object message) {
       logger.warn(message);
    }

    public void warn(Object message, Throwable t) {
       logger.warn(message,t);
    }

    public void fatal(Object message) {
       logger.fatal(message);
    }

    public void fatal(Object message, Throwable t) {
        logger.fatal(message,t);
    }

由于

4 个答案:

答案 0 :(得分:0)

为什么不使用Log logger = LogFactory.getLog(className);

如果要自动向日志添加更多数据,可以使用LoggerObject,但也许应该传递类而不是类名,如下所示

class LoggerObject<T> {
 private LoggerObject(Class<T> clazz){
  ...
 }
}

如果要限制传递的类,可以使用class LoggerObject<T extends SomeBaseClass>

编辑:
你应该知道这一点:

private static LoggerObject loggerobj;    

public static LoggerObject getLogger(String className)
{
  if (loggerobj==null)
  {
    loggerobj = new LoggerObject(className);
  }
  return loggerobj;
}

这将返回第一次调用的正确记录器,然后忽略传递的className

答案 1 :(得分:0)

LoggerObj是静态的,因此只存在于类级别。在第一次调用getLogger之后,变量被初始化并将继续将同一个对象返回给其他客户端。

看起来你想为记录器创建一个工厂,而是创建一个单例?

答案 2 :(得分:0)

将基础架构逻辑划分为独立实体的主要方法是可测试性。

使用构造函数(或setter)注入而不是在对象中创建对象,您可以使用模拟轻松替换此依赖项。但我不认为你基于记录器进行测试是最好的选择。

第二种方法是代码可移植性,但正如 @ThorbjørnRavnAndersen 已经提到slf4j将更好地完成此任务。

答案 3 :(得分:0)

我不完全确定你想要达到的目标,无论如何这似乎是错误的:

public static LoggerObject getLogger(String className)
    {
        if (loggerobj==null)
        {
         loggerobj = new LoggerObject(className);
        }
         return loggerobj;
    }

您实现了singleton模式,但是您存储了在第一个getLogger调用中传递的className(“foo”)。这意味着对getLoggger(“bar”)的所有后续调用都将返回一个className为“foo”的LoggerObject。如果您希望一个记录器对它们进行全局规则,那么它的名称应该是应用程序常量或可配置属性,而不是日志记录客户端恰好传递的第一个名称。

常规的Log4J习语是:

private static final Logger LOG = Logger.getLogger(abc.xyz.MyLoggingClient.class);

这将创建一个记录器,其参数的完全限定类名作为其名称。在log4j.properties中,您将拥有以下内容:

log4j.logger.abc.xyz.MyLoggingClient=WARN

请解释一下你不想用普通Log4j实现的目标。