2017-01-23
1 什么是注解
2 不使用注解示例
2.1 com.springioc.animal.Monkey
2.2 com.springioc.animal.Tiger
2.3 com.springioc.bean.Zoo
2.4 com.springioc.main.AppMain
2.5 Beans.xml
3 使用注解@Autowired示例
3.1 对成员变量使用@Autowired
3.2 将 @Autowired 注解标注在 Setter 方法上
3.3 将 @Autowired 注解标注在构造函数上
3.4 @Autowired(required = false)
4 使用注解@Resource示例
5 使用注解@Component示例
5.1 示例
5.2 component scan过滤方式
5.3 @Component、@Controller、@Repository,@Service
参考
1 什么是注解
传统的Spring做法是使用.xml文件来对bean进行注入。
注解配置相对于 XML 配置具有很多的优势:
- 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注解配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。
- 注解和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。
2 不使用注解示例
目录结构如下:
2.1 com.springioc.animal.Monkey
package com.springioc.animal; public class Monkey { private String monkeyName = "LaoEr"; public String toString() { return "MonkeyName:" + monkeyName; } }
2.2 com.springioc.animal.Tiger
package com.springioc.animal; public class Tiger { private String tigerName = "LaoDa"; public String toString() { return "TigerName:" + tigerName; } }
2.3 com.springioc.bean.Zoo
package com.springioc.bean; import com.springioc.animal.*; public class Zoo { private Tiger tiger; private Monkey monkey; public void setTiger(Tiger tiger) { this.tiger = tiger; } public void setMonkey(Monkey monkey) { this.monkey = monkey; } public Tiger getTiger() { return tiger; } public Monkey getMonkey() { return monkey; } public String toString() { return tiger + "\n" + monkey; } }
2.4 com.springioc.main.AppMain
package com.springioc.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.springioc.bean.Zoo; public class AppMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Zoo zoo = (Zoo) context.getBean("zoo"); System.out.println(zoo.toString()); } }
2.5 Beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" default-autowire="byType"> <bean id="zoo" class="com.springioc.bean.Zoo" > <property name="tiger" ref="tiger" /> <property name="monkey" ref="monkey" /> </bean> <bean id="tiger" class="com.springioc.animal.Tiger" /> <bean id="monkey" class="com.springioc.animal.Monkey" /> </beans>
运行结果:
TigerName:LaoDa MonkeyName:LaoEr
3 使用注解@Autowired示例
Spring 2.5 引入了 @Autowired 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
3.1 对成员变量使用@Autowired
对Zoo类的两个变量tiger和monkey使用注解Autowired,可以删除Set方法
package com.springioc.bean; import org.springframework.beans.factory.annotation.Autowired; import com.springioc.animal.*; public class Zoo { @Autowired private Tiger tiger; @Autowired private Monkey monkey; public String toString() { return tiger + "\n" + monkey; } }
Beans.xml
Beans.xml文件中删除zoo的property,增加(注册)AutowiredAnnotationBeanPostProcessor处理器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <!-- context:component-scan base-package="com.springioc.bean" / --> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <bean id="zoo" class="com.springioc.bean.Zoo" > </bean> <bean id="tiger" class="com.springioc.animal.Tiger" /> <bean id="monkey" class="com.springioc.animal.Monkey" /> </beans>
解读:
当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
按照上面的配置,Spring 将直接采用 Java 反射机制对 Zoo 中的 tiger 和 monkey 这两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,您大可将它们的 setter 方法(setTiger() 和 setOMonkey())从 Zoo 中删除。
注意:
Beans.xml文件中,可以用<context:component-scan base-package="com.springioc.bean" /> 替换 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> 。
因为<context:component-scan>会默认激活<context:annotation-config>功能的。而<context:annotation-config>会隐式地向 Spring 容器注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。
3.2 将 @Autowired 注解标注在 Setter 方法上
package com.springioc.bean; import org.springframework.beans.factory.annotation.Autowired; import com.springioc.animal.*; public class Zoo { private Tiger tiger; private Monkey monkey; @Autowired public void setTiger(Tiger tiger) { this.tiger = tiger; } @Autowired public void setMonkey(Monkey monkey) { this.monkey = monkey; } public Tiger getTiger() { return tiger; } public Monkey getMonkey() { return monkey; } public String toString() { return tiger + "\n" + monkey; } }