SpringMVC 源代码深度解析<context:component-scan>(扫描和注册的注解Bean)

    

    我们在SpringMVC开发项目中,有的用注解和XML配置Bean,这两种都各有自己的优势,数据源配置比较经常用XML配置,控制层依赖的service比较经常用注解等(在部署时比较不会改变的),我们经常比较常用的注解有@Component是通用标注,@Controller标注web控制器,@Service标注Servicec层的服务,@Respository标注DAO层的数据访问。SpringMVC启动时怎么被自动扫描然后解析并注册到Bean工厂中去(放到DefaultListableBeanFactory中的Map<String, BeanDefinition> beanDefinitionMap中 以BeanNamekey)?我们今天带着这些问题来了解分析这实现的过程,我们在分析之前先了解一下这些注解。

   @Controller标注web控制器,@Service标注Service层的服务,@Respository标注DAO层的数据访问。@Component是通用标注,只是定义为一个类为BeanSpringMVC会把所有添加@Component注解的类作为使用自动扫描注入配置路径下的备选对象。@Controller@Service\@Respository只是更加的细化,都是被@Component标注,所以我们比较不推荐使用@Component。源代码如下:

  

  1. @Target({ElementType.TYPE})  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Documented  
  4. @Component  
  5. public @interface Service {  
  6.     String value() default "";  
  7. }  
  8.   
  9. @Target({ElementType.TYPE})  
  10. @Retention(RetentionPolicy.RUNTIME)  
  11. @Documented  
  12. @Component  
  13. public @interface Controller {  
  14.     String value() default "";  
  15. }  
  16.   
  17. @Target({ElementType.TYPE})  
  18. @Retention(RetentionPolicy.RUNTIME)  
  19. @Documented  
  20. @Component  
  21. public @interface Repository {  
  22.     String value() default "";  
  23. }  
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
	String value() default "";
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
	String value() default "";
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
	String value() default "";
}

  都是有标示@Component

  我们在配置文件中,标示配置需要扫描哪些包下,也可以配置对某个包下不扫描,代码如下:

  1. <context:component-scan base-package="cn.test">  
  2.         <context:exclude-filter type="regex" expression="cn.test.*.*.controller"/>  
  3.         <context:exclude-filter type="regex" expression="cn.test.*.*.controller2"/>  
  4. </context:component-scan>  
<context:component-scan base-package="cn.test">
		<context:exclude-filter type="regex" expression="cn.test.*.*.controller"/>
		<context:exclude-filter type="regex" expression="cn.test.*.*.controller2"/>
</context:component-scan>

说明:

   <context:exclude-filter>指定的不扫描包,<context:exclude-filter>指定的扫描包

SpringMVC先读取配置文件,然后根据context:component-scan中属性base-package去扫描指定包下的classjar文件,把标示@Controller标注web控制器,@Service标注Servicec层的服务,@Respository标注DAO层的数据访问等注解的都获取,并注册为Bean类放到Bean工厂,我们接下来要分析的这个过程。我们平时项目开发都是这样的注解,实现MVC模式,代码如下:

  1. 例如:  
  2. //控制层  
  3. @Controller  
  4. @RequestMapping(value="/test")  
  5. public class TestController2 {  
  6.     @Autowired  
  7.     private TestService testService;  
  8.     @RequestMapping(value="/index")  
  9.     public String getIndex(Model model){  
  10.           
  11.         return "";  
  12.     }  
  13. }  
  14.   
  15. //服务层  
  16. @Service("testService")  
  17. public class TestServiceImpl implements  TestService{  
  18. }  
例如:
//控制层
@Controller
@RequestMapping(value="/test")
public class TestController2 {
	@Autowired
	private TestService testService;
	@RequestMapping(value="/index")
	public String getIndex(Model model){
		
		return "";
	}
}

//服务层
@Service("testService")
public class TestServiceImpl implements  TestService{
}

  我们今天的入口点就在这,因为解析注解的到注册,也是先读取配置文件并解析,在解析时扫描对应包下的Java类,里面有DefaultBeanDefinitionDocumentReader这个类,doRegisterBeanDefinitions这个方法实现解析配置文件的Bean,这边已经读取进来形成Document 形式存储,然后开始解析Bean,是由BeanDefinitionParserDelegate类实现的,BeanDefinitionParserDelegate完成具体Bean的解析(例如:bean标签、import标签等)这个在上一篇Sprin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值