【问题标题】:how to restrict object creation with certain dependency injection?如何通过某些依赖注入来限制对象创建?
【发布时间】:2011-07-10 21:52:56
【问题描述】:

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

公共类 LoggerObject { 私人 Logger 记录器; 私有静态 LoggerObject loggerobj; 私有常量数据管理器常量数据管理器; //默认 Log4J_FILE 路径 私人 LoggerObject(字符串类名) { 尝试 { DOMConfigurator.configure(this.getClass().getClassLoader().getResource(constantdatamanger.LOG4J_FILE)); logger =Logger.getLogger(className); } 捕捉(异常前) { System.out.println("DOMConfigurator 找不到文件"+ex.getMessage()); } } 公共静态 LoggerObject getLogger(String 类名) { if (loggerobj==null) { loggerobj = new LoggerObject(className); } 返回记录器obj; } 公共无效信息(对象消息) { logger.info(消息); } 公共无效信息(对象消息,Throwable t){ logger.info(消息,t); } 公共无效错误(对象消息){ logger.error(消息); } 公共无效错误(对象消息,Throwable t){ logger.error(消息,t); } 公共无效调试(对象消息){ logger.debug(消息); } 公共无效调试(对象消息,Throwable t){ logger.debug(消息,t); } 公共无效警告(对象消息){ logger.warn(消息); } 公共无效警告(对象消息,Throwable t){ logger.warn(消息,t); } 公共无效致命(对象消息){ logger.fatal(消息); } 公共无效致命(对象消息,Throwable t){ logger.fatal(消息,t); }

谢谢

【问题讨论】:

  • 限制如何?同时实现 slf4j API 可能会使您的代码更具可移植性。

标签: java


【解决方案1】:

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

如果你想自动向日志中添加更多数据,你可以使用 LoggerObject 但也许你应该传递类而不是类名,像这样

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

如果要限制传递哪些类,可以使用class LoggerObject&lt;T extends SomeBaseClass&gt;

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

private static LoggerObject loggerobj;    

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

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

【讨论】:

    【解决方案2】:

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

    您似乎想为记录器创建一个工厂,但却创建了一个单例?

    【讨论】:

      【解决方案3】:

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

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

      第二种方法是代码可移植性,但正如 @Thorbjørn Ravn Andersen 已经提到的那样,slf4j 会更好地完成这项任务。

      【讨论】:

        【解决方案4】:

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

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

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

        常规的 Log4J 习语是:

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

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

        log4j.logger.abc.xyz.MyLoggingClient=WARN
        

        请说明您希望实现哪些使用普通 Log4j 无法实现的目标。

        【讨论】:

          猜你喜欢
          • 2013-12-24
          • 2010-12-14
          • 1970-01-01
          • 2020-01-02
          • 2011-12-31
          • 1970-01-01
          • 1970-01-01
          • 2013-12-25
          • 2015-01-22
          相关资源
          最近更新 更多