spring的ioc的深入理解
前面总结了什么是spring的ioc,以及是如何实现的,最后的总结使用spring的好处是:
1、我们自己编写的组件并不需要实现框架指定的接口(这里指的框架是spring框架),因此可以轻松的将组件从spring中脱离,甚至不需要任何修改。
2、组件间的依赖关系减少,极大的改善了代码的可重用性。spring的依赖注入机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以指定,从而在相当程度上降低了组件之间的耦合。
?
第一点好处是实实在在的,确实,在基于spring开发的过程中,和spring框架本身的耦合是非常小的,或者说没有。
第二点更直接的来说,spring利用配置或者注解来进行对象的管理,将对象注入到ioc容器当中,然后从这个容器当中去取对象,而不是硬编码去获取一个具体的对象。这样当需要换当前的对象为实现了相同接口的另外一个对象时,代价是很小的。只需要将另外一个对象的类注册入ioc容器,然后在代码中,比如之前为:
?
ApplicationContext ctx = new FileSystemApplicationContext("bean.xml"); Action a = (Action)ctx.getBean("TheAction"); System.out.println(a.excute("Rod Johnson"));
?
?换成实现了相同接口的另外一个对象:
ApplicationContext ctx = new FileSystemApplicationContext("bean.xml"); Action a = (Action)ctx.getBean("TheSecondAction"); System.out.println(a.excute("Rod Johnson"));
?这样就ok了。
?
在jdk1.5之后,java开始支持注解,有了注解之后,spring针对bean的管理更加方便,更加灵活。
比如我指定了一个特定的service规范如下:
package com.myorg.springmvctutorial.web.service;import com.myorg.springmvctutorial.web.model.Customer;public interface CustomerService {void insert(Customer customer)throws Exception;}
?针对本规范的具体实现有如下两个具体类:
CustomerServiceImpl
@Service("test2")public class CustomerServiceImpl implements CustomerService{@Autowiredprivate CustomerDAO customerDAO;@Override@Transactionalpublic void insert(Customer customer)throws Exception {customerDAO.insert(customer);}}
?CustomerServiceImpltest
@Service("test1")public class CustomerServiceImpltest implements CustomerService{@Autowiredprivate CustomerDAO customerDAO;@Override@Transactionalpublic void insert(Customer customer)throws Exception {customerDAO.insert(customer);}}
?
当然在使用之前,是需要将其注册如spring的ioc容器的,具体注册就不在此处将了,不是本文的重点。
在controller当中的具体使用:
@Autowired@Qualifier("test2")private CustomerService customerService;@RequestMapping(value="/create")public String create(Customer customer,Model model) throws Exception{if(customer==null){model.addAttribute(new Customer());return "insertCustomer";}System.out.println(customer.getName());System.out.println(customer.getAge());customerService.insert(customer);return "insertCustomer";}
?
当同一个接口有多个具体实现时,有两个关键的注解@Service和@Qualifier。
首先需要为每个service加上名字,然后在controller当中使用时,用@Qualifier指定具体使用哪个service实现。
?
首先基于注解之后,spring针对service bean和dao bean等bean的配置减少了很多。同时基于注解,如果需要根据具体业务需求去换成实现了相同的接口的另外一个对象时,是非常简单的,按照上例,只需要将controller当中的
@Qualifier("test2")
?改为
@Qualifier("test1")
?即ok。
?
所以基于ioc容器进行对象管理,确实从很大程度上减少了组件之间的依赖关系。代码之间的耦合度也非常底,从上面的service从“test2”转变为“test1”就可以清楚的看到。