Spring之IOC与DI注解
Posted 居诸小筑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之IOC与DI注解相关的知识,希望对你有一定的参考价值。
Spring注释
Spring除了默认的使用XML配置文件的方式实现bean配置,也支持使用注解方式实现配置,这种方式效率更高,配置信息清晰,代码与对应配置相结合,方便开发阶段修改。所谓注解就是给程序看的提示信息,用作轻量级配置方式。
1. 注解实现IOC
1. <!--开启IOC包扫描-->
<context:component-scan base-package="cn.work.domain"/>
2.在配置的包中的类上使用 @Component 注解,则这个类会自动被注册为bean。
@Component
public class Person {
public Person(){
System.out.println("I has been inited");
}
}
3.关于bean的id
通常情况下,注解注册bean使用类名首字母小写为bean的id,但如果类名的第二个字母为大写,则保留原样,如:
cn.work.beans.Person --> <bean id="person" class="cn.work.beans.Person"/>
cn.work.beans.PErson --> <bean id="PErson" class="cn.work.beans.Person"/>
cn.work.beans.NBA --> <bean id="NBA" class="cn.work.beans.NBA"/>
4.也可以通过在@Component中配置value属性,明确的指定bean的id,如:
@Component("per")
注解方式实现工厂注册bean
Spring默认通过反射创建bean,如果某些bean没有无参构造器或创建过程非常复杂,则无法通过简单的反射创建bean,此时可以通过指定创建bean的工厂,令SpringIOC通过工厂来创建bean,从而进行注册。可以通过配置文件方式配置bean工厂,同样也可以通过注解配置bean工厂。
-
配置工厂类
工厂类必须放在包扫描目录下,且被@Component注解修饰。 -
配置工厂类中产生bean的方法
工厂中生产bean的方法要被@Bean修饰,这样才会被SpringIOC调用,并将返回的对象注册为Spring的bean,默认自动推断id,也可以通过value属性手工指定id。
//相当于<bean id="personFactory" class="cn.work.domain.PersonFactory"/>
@Component
public class TeacherFactory {
//相当于<bean id="person" factory-bean="personFactory" factory-method="getInstance"/>
@Bean("teacher")
public Teacher getInstance(){
return new Teacher("zs",11);
}
}
2. Spring 注解方式实现DI
<!--开启自动扫描-->
<context:component-scan base-package="cn.tedu.domain"/>
<!--注解方式DI-->
<context:annotation-config/>
注解方式注入spring内置支持的类型数据-非集合类型,可以通过@Value注解来实现spring内置支持的类型的属性的注入。
@Component
public class Student {
@Value("zs")
private String name;
@Value("19")
private int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
这种方式可以实现spring内置支持类型的注入,但将注入的值写死在了代码中,后续如果希望改变注入的值,必须来修改源代码。
可以将这些值配置到一个properties配置文件中,再在spring中进行引入。
注解方式注入spring内置支持的类型数据 - 集合类型,可以通过引入util名称空间,通过适当的util标签注册数据。
使用注解注入自定义bean类型数据: 在bean中的属性上通过@Autowired实现自定义bean类型的属性注入。
【案例】
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Component
public class Hero {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
@Value("#{@list01}")
private List<String> list;
@Value("#{@set01}")
private Set<String> set;
@Value("#{@map01}")
private Map<String,String> map;
@Value("#{@prop01}")
private Properties props;
@Override
public String toString() {
return "Hero{" +
"name=‘" + name + ‘‘‘ +
", age=" + age +
", list=" + list +
", set=" + set +
", map=" + map +
", props=" + props +
‘}‘;
}
}
//xml
<!--开启自动扫描-->
<context:component-scan base-package="cn.work.domain"/>
<!--注解方式DI-->
<context:annotation-config/>
<!--引入配置文件-->
<context:property-placeholder location="my.properties"/>
<!--预定义数据-->
<util:list id="list01">
<value>va</value>
<value>vb</value>
<value>vc</value>
<value>vd</value>
</util:list>
<util:set id="set01">
<value>v1</value>
<value>v2</value>
<value>v3</value>
</util:set>
<util:map id="map01">
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</util:map>
<util:properties id="prop01">
<prop key="k1">v1</prop>
<prop key="k2">v2</prop>
</util:properties>
//properties
name=u5f20u4e09
age=166
注:
当Spring容器解析到@Component注解时,创建当前类的bean在spring容器中进行管理,在创建bean的过程中发现了@Autowired注解,会根据当前bean类型,寻找在spring中是否存在该类型的bean。如果找到则直接注入,如果找不到还会检查是否有子孙类、实现类,如果存在唯一的则自动注入,如果还是没找到或找到多个,则进一步按照属性名对应id去查找,如果存在则注入,仍不存在则抛出异常。
也可以额外配置@Qualifier(value=" ")注解,强制要求按照id寻找bean,则此时会直接使用给定的id寻找bean。
也可以使用@Resource(name="id")指定注入给定id的bean,不建议大家使用。
以上是关于Spring之IOC与DI注解的主要内容,如果未能解决你的问题,请参考以下文章
Spring之手写SpringMVC5个注解(之IOC,DI优化)了解三级缓存
Java之Spring入门到精通IDEA版IoC和DI注解开发(一篇文章精通系列)