spring的核心就是IOC和AOP,这篇文章就简单介绍一下IOC(控制反转)。
一、IOC与DI的比较:
不管在spring的学习,还是网上的博客,经常会讲到ioc与di的区别,我相信很多人是搞不清它两者的区别,会认为两者是一样的。其实IOC,它是一种思想,把原来我们控制对象的生命周期,转向给spring控制,spring容器会控制这个对象的生命周期。而DI是IOC的一种结果,因为控制反转后,spring可以对其做很多事情,比如注入DI,也可以对其做其它事情,比如销毁。所以说DI是IOC的一个具体的操作。
二、<mvc:annotation-driven/>和<context:component-scan>的比较
在spring的开发中,我们经常会看到配置文件中配置<mvc:annotation-driven/>和<context:component-scan>这两个注解,他们到底是什么意义,下面我会讲解。
随着spring的高版本的流行,在高版本中的注解的开发也成为了一种主流的方式,但是在java代码中使用注解,要让它生效的话,就必须配置这两个注解。
<context:annotation-config/>:不建议用
1.如果你想使用@Autowired注解,那么就必须事先在 spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。
2.如果想使用@Resource、@PostConstruct、@PreDestroy等注解就必须声明CommonAnnotationBeanPostProcessor
3.如果想使用@PersistenceContext注解,就必须声明PersistenceAnnotationBeanPostProcessor的Bean。
4.如果想使用 @Required的注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean。
使用<context:annotation- config/>隐式地向 Spring容器注册这4个BeanPostProcessor :
即<context:annotation-config/>是用来使上述注解起作用的,也就是说激活已经在application context中注册的bean。 之所以这样说是因为<context:annotation-config />仅能够在已经在已经注册过的bean上面起作用。对于没有在spring容器中注册的bean,它并不能执行任何操作,也就是说如果你并没有spring容器中注册过bean(spring配置文件中配置bean就是注册),那么上述的那些注解并不会在你未注册过的bean中起作用。
AutowiredAnnotationBeanPostProcessor、
RequiredAnnotationBeanPostProcessor、
CommonAnnotationBeanPostProcessor以及
PersistenceAnnotationBeanPostProcessor
<mvc:annotation-driven/>
这个配置主要是处理Request、Response、Exception等数据,这个标签对应的实现类是
org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
仔细阅读它的注释文档可以很明显的看到这个类的作用。解析这个文档:
这个类主要注册8个类的实例:
1.RequestMappingHandlerMapping
2.BeanNameUrlHandlerMapping
3.RequestMappingHandlerAdapter
4.HttpRequestHandlerAdapter
5.SimpleControllerHandlerAdapter
6.ExceptionHandlerExceptionResolver
7.ResponseStatusExceptionResolver
8.DefaultHandlerExceptionResolver
1是处理@RequestMapping注解的,2.将controller类的名字映射为请求url。1和2都实现了HandlerMapping接口,用来处理请求映射。
3是处理@Controller注解的控制器类,4是处理继承HttpRequestHandlerAdapter类的控制器类,5.处理继承SimpleControllerHandlerAdapter类的控制器。所以这三个是用来处理请求的。具体点说就是确定调用哪个controller的哪个方法来处理当前请求。
6,7,8全部继承AbstractHandlerExceptionResolver,这个类实现HandlerExceptionResolver,该接口定义:接口实现的对象可以解决处理器映射、执行期间抛出的异常,还有错误的视图。
所以<annotaion-driven/>标签主要是用来帮助我们处理请求映射,决定是哪个controller的哪个方法来处理当前请求,异常处理。
<context:component-scan>
<context:component-scan>做了<context:annotation-config>要做的事情,还额外支持@Component,@Repository,@Service,@Controller注解。并且<context:component-scan>扫描base-package并且在application context中注册扫描的beans。所以配置<context:component-scan>就不需要配置<context:annotation-config/>。
三、IOC
1、 在spring配置文件spring/application-config.xml中配置:
这种方式可以。
2、通过注解的方式
注意:要使用注解的方式DI的话,必须在对应的类上添加@Repository、@Service、@Component、@Controller纳入spring管理。也就是通过添加这几个注解的话,spring可以自动注入对应的类的对象。
3、混合用
这样混合用的话,会有一定的问题,spring在注入的时候会找不到cityDao对象。也就是如果两个对象如果存在一定的依赖关系的话,不能使用注解创建一个对象,spring配置另一个对象,然后通过注解注入或者spring配置注入,这样的做法都是错误的。
如果不存在依赖的对象的话,也就是可能通过这两种方式创建对象。
四、spring配置文件的注解
@Configuration与@Bean
注意:虽然@Configuration相当于spring的配置文件,但是这种方式可以与spring注解方式一起用,也就是结合下面的代码,也是可以注入。