内容参考《Spring5高级编程》。
IoC概述:IoC意为控制反转。IoC的核心是DI,意为依赖注入。旨在提供一种更简单的机制设置依赖项,并在整个生命周期中去管理这些依赖项。
通常 IoC可以分解为两种子类型:依赖注入和依赖查找
依赖查找:依赖拉取和上下文依赖查找
依赖注入:构造函数和setter依赖注入
依赖拉取
public static void main(String[] args){
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
TestDao tt=ctx.getBean("test",TestDao.class);
tt.sayhello();
}
构造函数依赖注入
public Constructorinjection (Dependency dependency)
public class Constructorinjection {
private Dependency dependency;
public Constructorinjection (Dependency dependency) {
this .dependency = dependency;
}
@Override
publiC String toString () {
return dependency.toString();}
}
setter依赖注入
public void setDependency(Dependency dependency)
public class Constructorinjection {
private Dependency dependency;
public void setDependency(Dependency dependency) {
this .dependency = dependency;
}
@Override
publiC String toString () {
return dependency.toString();}
}
区别:setter注入可以在没有依赖项的情况下创建对象,耦合度较低。
setter可以在接口上声明依赖项,但除配置参数等信息,不应定义。
以上为IoC的基本介绍
public static void main(String[] args){
// 初始化工厂对象
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//初始化Bean读取器
XmlBeanDefinitionReader rdr = new XmlBeanDefinitionReader(factory);
//加载XML实例
rdr.loadBeanDefinitions(new ClassPathResource("spring/xml-bean-factory-config.xml");
Oracle oracle=(Oracle)factory.getBean("oracle");
System.out.println(oracle.defineMeaning());
}
设置Spring配置选项:可xml,java注解,也可混合使用。
XML:
<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer"
p:messageProvider-ref]"provider"/>
注解:
1. @Component("provider") //注解依赖项
2. @Service("renderer") //注解依赖对象
3. @Autowired //查找该类型的Bean并作为调用该方法的参数,该注解在依赖对象的构造方法或setter上。
其中注解形式须在XML中另加:
<context:component-scan base-package="com.apress.prospring5.ch3.annotation"/>
只要注解和XML写正确并没有冲突,单纯XML,注解或混合并不影响ApplicationContext实现依赖注入
代码如下:
public static void main(String[] args){
GenericXmlApplicationContext ctx=new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-xml.xml");
ctx.refresh();
Oracle oracle=(Oracle)ctx.getBean("oracle");
System.out.println(oracle.defineMeaning());
ctx.close();
}
使用一个配置类来代替以上的application.xml
1. @Configuration //注解在配置类类名上
2. @Bean //注解在创建的方法上,可获取Prodiver,rendder实例
配置类略,使用如下:
public static void main(String[] args){
//初始化并加载配置类
ApplicationContext ctx = new AnnotationfigApplicationContext(
HelloWorldConfigurationContext.class);
Oracle oracle=(Oracle)ctx.getBean("oracle");
System.out.println(oracle.defineMeaning());
}
<context:component-scan base-package="com.apress.prospring5.ch3.annotation"/>
+ XML
// 等效于:
@ComponentScan(basePackages={
"com.apress.prospring5.ch3.annotation"})
@Configuration
+ 配置类
使用setter或构造函数实现的XML中bean配置
<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer">
<property name="provider" ref="provider">
//name:为属性
</bean>
//新版本
<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer"
p:messageProvider-ref="provider"/>
//注解
@Autowired
+ settter方法
<bean id="provider" class="com.project.provider">
<constructor-arg index=0 value="i hope"/>
<bean>
// 新版本
<bean id="provider" class="com.project.provider"
c:message="i hope"/>
// c:_0="i hope"/> 构造函数参数索引
//注解
@Autowired
+ 构造函数
通过@Autowired注解来注解类成员,依赖项直接注入字段中,不需构造函数和setter。(其中遇到的类成员为私有问题可通过反射解决)
一般不推荐使用
@Autowired
+ 类成员
@Component("injectSimpleConfig") //与类名一致?
<!--private String name = "HGF";-->
<!--private int age = 39;-->
// injectSimpleConfig 配置在xml中
<bean id="injectSimpleConfig" class="com.apress.prospring5.ch3.xml.InjectSimpleConfig"/>
<bean id="injectSimpleSpel" class="com.apress.prospring5.ch3.xml.InjectSimpleSpel"
p:name="#{injectSimpleConfig.name}"
p:age="#{
injectSimpleConfig.age+1}/>
<!--name = "HGF";-->
<!--age = 40;-->
一般情况下,@Service 与 @Component 并无差别,@Service是@Component 的一个特例。表明注解放入类正在项应用程序中的其他层提供业务服务。
实现将一个bean注入另一个bean
依赖对象定义的setter方法,比如是setOracle(),被注入的bean类型不一定是定义的确切类型。如果是接口,被注入的bean类型必须实现该接口。如果声明的是一个类,必须是相同的类型或者是子类型。
<bean id="oracle" name="wiseworm" class="...BookwormOracle"/>
<bean id="injectRef" class="...">
<property name="oracle">
<ref bean="oracle"/>
//
</property>
</bean>