17

@Autowired使用annotation 和newkey有什么区别?让我们在一个班级里有什么区别:

@Autowired private UserDao userdao;

private UserDao userDao = new UserDaoImpl();

对性能有影响吗?

4

4 回答 4

21

除了其他人已经提到的低耦合之外,一个主要的区别是,使用该new方法,无论您是否愿意,每次都会获得一个新对象。即使UserDaoImpl是可重用的、无状态的和线程安全的(DAO 类应该努力做到这一点),您仍然会在每个需要它们的地方创建它们的新实例。

起初这可能不是一个大问题,但考虑到随着对象图的增长——UserDaoImpl可能需要一个 Hibernate 会话,它需要一个 DataSource,它需要一个 JDBC 连接——它很快就会变成很多必须创建和初始化的对象一遍又一遍地。当你在你的代码中依赖时new,你也在一大堆地方展开初始化逻辑。就像在这个例子中一样,你需要在你的 UserDaoImpl 中有代码来打开一个带有正确参数的 JDBC 连接,但是所有其他的 DAO 类都必须做同样的事情。

这就是控制反转 (IoC) 的用武之地。它旨在通过将对象创建和生命周期与对象绑定和使用解耦来解决这些问题。IoC 最基本的应用是一个简单的工厂类。更复杂的方法是依赖注入,例如 Spring。

对性能有影响吗?

是的,但它很可能不会很重要。使用 Springs 依赖注入会在启动时花费更多,因为必须初始化容器并设置所有托管对象。但是,由于您不会创建托管对象的新实例(假设您是这样设计它们的),因此您将从更少的 GC 负载和更少的对象创建中获得一些运行时性能。

但是,您的最大收获将在于应用程序的可维护性和健壮性。

于 2012-10-12T08:12:31.677 回答
7

上面的评论是正确的,但在这里我要添加一些对你有帮助的例子。

看,我们有 100 个使用UserDao类的类,你会得到这样的 dao 实例: private UserDao userDao = new UserDaoImpl();在 100 个地方,

几周后需求发生了变化,我们需要使用LdapUserDao或类似的东西

class LdapUserDao implements UserDao{

}

实现UserDao。你做什么工作?你如何处理你的new关键词,你将 impl 类绑定到使用中。

如果您在 100 个地方使用 @Autowired 然后从一个地方(如果您使用基于 xml 的配置,那么只需转到 xml 并从 xml 切换到另一个 UserDao,如果注释转到该组件并将 Spring 注释切换到正确的一个)管理它,所以它出现在 100 个地方。这就是所谓的DI模式。这是DI的全部目的

另一个重要的事情是使用 spring 注释,即使您可以管理对象范围,但是使用 new 关键字没有办法(除非您使用愚蠢的单例或类似的东西),我确信使用 new 关键字您不能拥有

  Prototype
  Request
  Single

作用域对象

在性能方面,很难说,除非看你的代码。但我确信在最坏的情况下它们可能具有相同的性能,否则弹簧方式很快,因为据我所知,dao 类应该是单例的,而不是原型,所以整个项目你将以弹簧方式在 userdao 对象上拥有new方式,这取决于在哪里您正在失去对 dao 对象的引用。但离开表演。不要考虑性能而不是良好的设计。一直以来,第一次以良好的方式(而不是快速的方式)以良好的设计制作它,然后看看它的性能。

于 2012-10-12T02:08:25.250 回答
3

如果你使用,你会得到 NullPointerException

private UserDao userDao = new UserDaoImpl();

因为它没有设置 *context.xml 中声明的会话引用。

于 2015-12-01T07:59:46.077 回答
1

在运行时,您将在这两种情况下都获得一个UserDaoImpluserdao属性中分配的实例。

但是第一种方法意味着使用依赖注入模式,它比第二种方法有一些优势:

  • 您的类现在依赖于一个接口,因此它可以与 UserDao 的任何实现一起使用(可能一个使用 RDBMS,另一个使用 XML 文件作为存储库)
  • 由于您现在依赖于接口,因此单元测试和模拟非常简单明了。
  • 低耦合是代码中的一个很好的属性。

所以你应该更喜欢第二种方法而不是第一种,特别是如果你已经在使用 Spring(这就是Inversion-Of-Control容器背后的想法)

于 2012-10-12T01:05:23.257 回答