《Spring IOC 学习——注解工作机制》
来源:互联网 发布:苏州网络教育多少钱 编辑:程序博客网 时间:2024/06/03 23:45
在没有引入spring框架前,在类与类之间的调用关系通过new关键字进行实例化对象,进而调用对象的方法或者属性。在引入spring框架后,我们开始使用spring容器进行IOC注入,在spring的配置文件applicationContext.xml文件里,配置相应类的bean节点,在不配置懒加载bean节点的前提下,当配置文件applicationContext加载后,会自动实例化所有的singleton的bean并缓存在容器中供我们类的调用。再后来,我们不再在xml文件中配置bean节点,而是配置<context:component-scan/>标签自动扫描包,通过注解的方式,被spring容器进行管理。
现在我来简单描述一下这三个过程:
1·没有引入spring之前:
HelloWorld a=new HelloWorld();
2·在引入Spring容器后,在applicationContext.xml文件里,配置类HelloWorld节点,
<beanid="helloWorld"class="com.dynamic.study1.HelloWorld"></bean>
3·在使用注解后:
@Componentpublic class HelloWorld{}
这三个声明方式虽然变了,但是原理还是一样的。
在2的过程中,是通过反射机制动态加载的类HelloWorld,其实质和new实例化是一样的,即:
Class t=Class.forName("package.A"); t.newInstance();和
A a = new A();实现的效果是一致的。所以说1和2的变化过程实质是一样的。
那在2到3的变化过程中,是怎么工作机制法呢?换句话说,spring注解是如何工作的呢?Spring是如何读取注解信息,并注入到bean容器中的?
先来看以下demo:
A自定义注解:
package com.dynamic.spring.annotations;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface MyComponent {String value() default "";}
B java普通类:
package com.dynamic.spring.annotations;@MyComponentpublic class User {public User(){System.out.println("the User class.......");}}
C Spring配置文件applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 配置自动扫描包 --><context:component-scan base-package="com.dynamic.spring.annotations"></context:component-scan></beans>
D客户端:
package com.dynamic.spring.annotations;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args){ApplicationContext atc=new ClassPathXmlApplicationContext("applicationContext.xml");atc.getBean(User.class);}}
执行这个例子,就会发现,自定义注解@MyComponent被spring容器加载进来了。
执行结果:
解析:为什么自定义的注解也能够像@Service,@Respository等注解被spring的配置文件扫描到?
查看Spring的源码会发现,Spring是使用ClassPathScanningCandidateComponentProvider扫描package,
这个类的 registerDefaultFilters 方法有这样几行代码:
/** * Register the default filter for {@link Component @Component}. * <p>This will implicitly register all annotations that have the * {@link Component @Component} meta-annotation including the * {@link Repository @Repository}, {@link Service @Service}, and * {@link Controller @Controller} stereotype annotations. * <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and * JSR-330's {@link javax.inject.Named} annotations, if available. * */@SuppressWarnings("unchecked")protected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}
这里就会发现Spring在扫描类信息的使用只会判断被@Component注解的类,所以任何自定义的注解只要带上@Component(当然还要有Stringvalue() default"";的方法,因为Spring的Bean都是有beanName唯一标示的),都可以被Spring扫描到,并注入容器内。
- 《Spring IOC 学习——注解工作机制》
- Spring工作机制,IOC容器
- Spring Ioc实现机制——简析
- Spring学习3—控制反转(IOC)基于Annotation(注解)的依赖注入实现
- 【10】框架学习—Spring的IOC容器之注解方式与AOP技术
- Spring— Acegi工作机制
- Spring学习一之IOC工作原理
- Spring框架学习之二(IOC机制)
- Spring IOC 常用注解
- Spring IoC 注解配置
- Spring IOC 常用注解
- Spring ioc注解教程
- 关于Spring 注解 IOC
- Spring IoC常用注解
- spring ioc及注解
- Spring IoC 注解配置
- Spring常用注解---IoC
- Spring使用IOC注解
- webpack学习笔记-3-autoprefixer-loader
- 14. SourceInsight使用
- 增值竞争力,卓易科技与诺亚信携手而行
- 微信和支付宝 app user-agent
- 突破sql 注入过滤Union+SELECT 继续射下去
- 《Spring IOC 学习——注解工作机制》
- canvas画月亮
- java定时器使用
- JAVA枚举类型
- Python常犯错误集合
- 判断一颗二叉树是否是完全二叉树
- 我的渗透利器
- Ubuntu Linux更新VMware Tools到open-vm-tools笔记
- 2017.6.25仿网易考拉排版记录