如何通过某些依赖注入来限制对象创建?

Posted

技术标签:

【中文标题】如何通过某些依赖注入来限制对象创建?【英文标题】: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 可能会使您的代码更具可移植性。 【参考方案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 无法实现的目标。

【讨论】:

以上是关于如何通过某些依赖注入来限制对象创建?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs 学习笔记依赖注入

Spring基础知识1--环境搭建bean创建依赖注入注解注入

Android Dragger2快速入门浅析

如何使用依赖注入多次创建对象

Spring详解------DI依赖注入

IOC控制反转与DI依赖注入