是否有可能确保只有Spring可以实例化一个类,而不是在编译时使用关键字“new”?(避免意外实例化)
谢谢!
是否有可能确保只有Spring可以实例化一个类,而不是在编译时使用关键字“new”?(避免意外实例化)
谢谢!
//CONSTRUCTOR
public MyClass() {
try {
throw new RuntimeException("Must be instantiated from with Spring container!");
}
catch (RuntimeException e) {
StackTraceElement[] els = e.getStackTrace();
//NOW WALK UP STACK AND re-throw if you don't find a springframework package
boolean foundSpring = false;
for (StackTraceElements el : els) {
if (el.getDeclaringClass().startsWith("org.springframework")) {
foundSpring = true; break;
}
}
if (!foundSpring) throw e;
}
}
我真的不建议这样做!
private
构造函数、使用静态工厂)也可以从Java中使用。因此,请求的目的(使某些东西无法在Spring容器之外工作)将无法实现。 - oxbow_lakes虽然我能理解你为什么想要确保一个类只能由Spring实例化,但这实际上并不是一个好主意。依赖注入的目的之一是在测试期间轻松模拟一个类。因此,在单元测试期间手动实例化各种依赖项和模拟依赖项应该是可能的。依赖注入的存在是为了让生活更轻松,所以通常最好使用DI进行实例化,但也有一些情况下使用new是完全合理的,人们应该小心不要将任何设计模式或习惯用法推向极端。如果你担心你的开发人员会在应该使用DI的地方使用new,那么最好的解决方案就是建立代码审查。
我不确定Spring是否支持这个功能,因为我没有尝试过,并且已经有一段时间没有使用Spring了。然而,在另一个IOC容器中,我曾经采取的一个巧妙的方法是将希望作为注入接口返回的类作为抽象类,让IOC容器将其作为派生类实例返回。这样,没有人可以创建该类的实例(因为它是抽象的),并且容器可以返回此类的派生类。
容器本身将生成派生类的定义,因此不必担心有人尝试构造其中之一。
在构造函数调用周围编写一个方面,并且如果不是通过Spring,则中止
虽然不知道Spring,但如果你想在创建新实例时有一些控制权,应将构造函数设为私有,并在类内部创建public static YourClass getInstance()
方法来处理检查并返回该对象的新实例。然后,您可以创建具有调用getInstance()的构造函数的新类... 并将该类交给Spring。很快您就会发现,在Spring之外有'非法'调用的地方...