为什么不考虑使用Spring的IOC来管理bean?

风花狂月 发布于 2015/04/23 16:29
阅读 1K+
收藏 2

@JFinal 你好,想跟你请教个问题:

我看到您在一些回答网友文章的帖子中说建议放弃Spring,但是我觉得Spring的IOC模式挺不错,很适合在Web中的开发使用,那么您建议放弃Spring的理由是什么呢???为什么您更倾向于使用单例模式维护bean?难道就是因为编码上更简洁了吗???如:我现在写一个Service

public class UserService {
    public static UserService me = new UserService();
    public void getCurrutUser(){
        System.out.println(User.dao.getName());
    }
}

这是您的推荐的写法(这个Service方法如果被其他的Controller代码使用的话就存在多个单例被调用,如果是并发量高的情况下,会不会出现线程不可靠的问题),如果是用Spring的话

public class UserService {

    @Autowired
    private User user;

    public void getCurrutUser(){
        System.out.println(user.getName());
    }
}

为什么不使用Spring的注入方式,而采用单例模式作为编码的写法,您是怎么考虑的,可以和我分析一下吗???谢谢



加载中
1
JFinal
JFinal

    问题很多,也很大,在此仅简单聊一下:

1:jfinal 为啥没有 IOC

    通常来说 IOC 是为了实现 AOP,而 AOP 最常应用于权限管理及声名式事务,而 jfinal 提供的拦截器已经实现了AOP,并且可以避免 IOC 带来的大量 XML 配置或者 Annotation, Annotation 也是配置的一种形式,jfinal 主张尽可能减少配置,这样才能实现极速开发的目标。

      当前通常使用 Spring 的人无论要不要 AOP,都将controller、service、dao、model 等等各层次通过 xml 一层一层组装起来,这是对 AOP 的一种滥用,而且极大增加了代码量、降低了开发效率,这是在当下飞速发展的移动互联网背景下非常不经济的方式。

2:关于单例模式

    与楼主所说的相反,jfinal 并没有主张单例模式,而只是当 Service 没有状态时,建议在 controller 中 private static Service service = new Service() 这样创建一个 static 属性,由于controller 是非单例的,而 service 又是无状态的,这种方式可以避免每个请求过来都创建 service 对象,节省时空,所以这里主要是根据项目实际情况来做选择。

3:有关线程安全

     对于 controller 来说,是每个请求过来都创建对象,所以是线程安全的。对于controller 所依赖的 service 属性,只要是无状态的就可以直接 static Service service 创建一次,让多线程共享,也不存在线程安全问题。如果 Service 是状态的,如果是轻量级的对象,每次 new Service().doSomeThing() 就可以。

4:注入、单例模式

   注入就需要 IOC,有了 IOC 就有一堆配置,有了一堆配置就不是极速开发,不是极速开发成本就高。jfinal 并未刻意要求过使用单例模式,相反而是建议直接使用 new 出对象来替代传统的 IOC 注入方式,而在 controller 中 static Service 的做法本质上也不是单例,只是在servcie 无状态时的一种节省时空的写法。

0
风花狂月
风花狂月

引用来自“JFinal”的评论

    问题很多,也很大,在此仅简单聊一下:

1:jfinal 为啥没有 IOC

    通常来说 IOC 是为了实现 AOP,而 AOP 最常应用于权限管理及声名式事务,而 jfinal 提供的拦截器已经实现了AOP,并且可以避免 IOC 带来的大量 XML 配置或者 Annotation, Annotation 也是配置的一种形式,jfinal 主张心可能减少配置,这样才能实现极速开发的目标。

      当前通常使用 Spring 的人无论要不要 AOP,都将controller、service、dao、model 等等各层次通过 xml 一层一层组装起来,这是对 AOP 的一种滥用,而且极大增加了代码量、降低了开发效率,这是在当下飞速发展的移动互联网背景下非常不经济的方式。

2:关于单例模式

    与楼主所说的相反,jfinal 并没有主张单例模式,而只是当 Service 没有状态时,建议在 controller 中 private static Service service = new Service() 这样创建一个 static 属性,由于controller 是非单例的,而 service 又是无状态的,这种方式可以避免每个请求过来都创建 service 对象,节省时空,所以这里主要是根据项目实际情况来做选择。

3:有关线程安全

     对于 controller 来说,是每个请求过来都创建对象,所以是线程安全的。对于controller 所依赖的 service 属性,只要是无状态的就可以直接 static Service service 创建一次,让多线程共享,也不存在线程安全问题。如果 Service 是状态的,如果是轻量级的对象,每次 new Service().doSomeThing() 就可以。

4:注入、单例模式

   注入就需要 IOC,有了 IOC 就有一堆配置,有了一堆配置就不是极速开发,不是极速开发成本就高。jfinal 并未刻意要求过使用单例模式,相反而是建议直接使用 new 出对象来替代传统的 IOC 注入方式,而在 controller 中 static Service 的做法本质上也不是单例,只是在servcie 无状态时的一种节省时空的写法。

非常感觉@Jfinal可以解决我的一些疑惑,但是我看了您说的第1点和第4点又有新的疑惑了,IOC需要一堆配置,那么我完全可以写一个方法在应用启动的时候将所有我想管理的bean扫描一遍放入内存中,当对象创建时候在去注入(像Spring是有自动扫描的功能的),然后在bean上通过Annotation 来标识我想注入的类,虽然Annotation 也是配置的一种,但是只要我将之前写的那个扫描的方法取消了,Annotation 本身对对象是没有任何影响的,难道这样就不算是极速开发了吗?因为我感觉使用IOC的注入方式可以很好的解决硬编码的一些问题,同时由于现在我们的项目已经全面转型使用Jfinal框架(嘿嘿,我大力向领导推荐使用,最后终于成功了)我在编码model层代码时,也碰到一些疑惑,因为我使用的是Jfinal默认的ORM模式,每次需要数据的时候我要getXX("数据表中字段的名字"),这样我感觉很麻烦,还有就是当我需要序列号这个对象时(我通常用的是fastJson这个工具)我不得不为他写上相应的属性,那么我在想为何不直接在model的代码上加上属性,让ORM直接把表中字段映射到对象的属性中呢?关于这点也是我最近开发中碰到的一个疑惑:比如

public class User {
    private String name;
    private Integer age;

//get 和 set 省略

}

虽然说Jfinal这样做完全剔除了臃肿的ORM框架,但是就如同您所说的极速开发,这样做我觉得反而加长了开发效率,虽然代码量确实减少了很多,能否给我讲讲您在ORM层的考虑,非常感谢


0
风花狂月
风花狂月
@JFinal  

非常感谢@JFinal可以解决我的一些疑惑,但是我看了您说的第1点和第4点又有新的疑惑了,IOC需要一堆配置,那么我完全可以写一个方法在应用启动的时候将所有我想管理的bean扫描一遍放入内存中,当对象创建时候在去注入(像Spring是有自动扫描的功能的),然后在bean上通过Annotation 来标识我想注入的类,虽然Annotation 也是配置的一种,但是只要我将之前写的那个扫描的方法取消了,Annotation 本身对对象是没有任何影响的,难道这样就不算是极速开发了吗?因为我感觉使用IOC的注入方式可以很好的解决硬编码的一些问题,同时由于现在我们的项目已经全面转型使用Jfinal框架(嘿嘿,我大力向领导推荐使用,最后终于成功了)我在编码model层代码时,也碰到一些疑惑,因为我使用的是Jfinal默认的ORM模式,每次需要数据的时候我要getXX("数据表中字段的名字"),这样我感觉很麻烦,还有就是当我需要序列号这个对象时(我通常用的是fastJson这个工具)我不得不为他写上相应的属性,那么我在想为何不直接在model的代码上加上属性,让ORM直接把表中字段映射到对象的属性中呢?关于这点也是我最近开发中碰到的一个疑惑:比如

public class User {
    private String name;
    private Integer age;

//get 和 set 省略

}

虽然说Jfinal这样做完全剔除了臃肿的ORM框架,但是就如同您所说的极速开发,这样做我觉得反而加长了开发效率,虽然代码量确实减少了很多,能否给我讲讲您在ORM层的考虑,非常感谢

0
JFinal
JFinal

引用来自“slashchenxiaojun”的评论

@JFinal  

非常感谢@JFinal可以解决我的一些疑惑,但是我看了您说的第1点和第4点又有新的疑惑了,IOC需要一堆配置,那么我完全可以写一个方法在应用启动的时候将所有我想管理的bean扫描一遍放入内存中,当对象创建时候在去注入(像Spring是有自动扫描的功能的),然后在bean上通过Annotation 来标识我想注入的类,虽然Annotation 也是配置的一种,但是只要我将之前写的那个扫描的方法取消了,Annotation 本身对对象是没有任何影响的,难道这样就不算是极速开发了吗?因为我感觉使用IOC的注入方式可以很好的解决硬编码的一些问题,同时由于现在我们的项目已经全面转型使用Jfinal框架(嘿嘿,我大力向领导推荐使用,最后终于成功了)我在编码model层代码时,也碰到一些疑惑,因为我使用的是Jfinal默认的ORM模式,每次需要数据的时候我要getXX("数据表中字段的名字"),这样我感觉很麻烦,还有就是当我需要序列号这个对象时(我通常用的是fastJson这个工具)我不得不为他写上相应的属性,那么我在想为何不直接在model的代码上加上属性,让ORM直接把表中字段映射到对象的属性中呢?关于这点也是我最近开发中碰到的一个疑惑:比如

public class User {
    private String name;
    private Integer age;

//get 和 set 省略

}

虽然说Jfinal这样做完全剔除了臃肿的ORM框架,但是就如同您所说的极速开发,这样做我觉得反而加长了开发效率,虽然代码量确实减少了很多,能否给我讲讲您在ORM层的考虑,非常感谢

    什么叫硬编码问题? 这一直是个伪命题,难道将所有的对象组装全部用外部的 xml 或者 annotation 这样就就实现了非硬编码? 即便这样做了那现实的意义在哪里?很多人就是因为这种思维模式,造成了 java 的 new 关键字都不会用了,甚至慢慢没有察觉到 new 关键字的存在。

    IOC、AOP 应该用到需要的地方,而不是用在所有地方,接口与抽象也应该用在需要的地方,而现状态是 service 层来个 interface 来再个 impl,dao 层也来一个 interface 和 impl,造成了一个极度简单的功能需要一堆代码来实现,绝大部分开发是工程性的活动,而非理论研究,工程性的东西就得讲求经济、实际,而非理论上觉系统在未来所有部分都是接口依赖,都是可以用配置的方式来切换实现类,这种理想化的想法通常在未来永远不会发生,而开发者为了这个未来不存在的理想付出了实实在在的时间和精力。

    最后 jfinal 的 model 从来没有限制开发者不去做成传统 java bean:

public class User extends Model<User> {

    public void setUserName(String userName) {

         this.set("userName", userName);

     }

     public String getUserName() {

       return this.get("userName");

    }

}

    只要开发者无所谓不厌其烦写这类无聊的重复代码就可以。其实用 jfinal 开发一段时间感觉受一下这些疑问就没有了。

返回顶部
顶部