1 IOC介绍
1.1 什么是Spring的IoC?
不反转的情况:开发人员直接在code中new 对象出来,开发人员主动管理对象。
IOC:Inversion of Control 控制反转,控制指的是对实现类的控制,反转指的是这种控制权从调用类中移除,交给第三方决定.即某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。
对象的创建、初始化、等操作交由Spring容器进行管理。
DI:Dependency Injection 依赖注入,让调用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。
1.2 为什么要使用IOC?
实现解耦(可以实现业务对象之间的解耦),减少对代码的改动。
1.3 已经可以体现IOC思想的例子
Servlet。
【Servlet的使用方法】
- 创建类继承Servlet
- 在web.xml中注册Servlet
<servlet-name>myservlet</servlet-name>
<servlet-class>com.xxx.xx.controller.MyServlet</servlet-class>
使用过程中没有手动创建MyServlet对象。对象是有tomcat容器进行创建的。Tomcat作为容器里面存放了Servlet、Listener和Filter等对象。
1.4 什么样的对象应该,什么样的不应该放入到容器中托管
【应该放入的】
dao类,service类、controller和工具类等。
【不应该放入的】
实体类对象:这些地来自于数据库的。
Tomcat托管的对象:servlet、listener和filter等。
2 Spring IoC对于java bean的创建有哪几种方式?
DI的实现(创建对象,给属性赋值)有两种:
- 在Spring配置文件中,使用标签和属性完成,称为基于XML的DI实现。
- 基于注解的DI实现
【DI的语法分类】
- set注入:spring调用类的set方法。
- 构造注入:spring调用类的有参数构造方法。
2.1 注解方式
2.1.1 @Component
创建对象,等同于. value是对象的名称,等同于bean的id,是惟一的。
@Component(value="myStudent")
public class Student {
}
2.1.2 @Repository、@Service和@Controller
Repository用在持久层的。
和@Componet的功能一致,放在dao的实现类上面,表示创建dao对象。dao对象是可以访问数据库的。
Service和@Componet的功能一致
用在业务层的
放在Service的实现类上面,创建Service对象,Service对象是做业务处理,可以有事务等功能的。
Controller和@Componet的功能一致
用在控制器上面的。
放在处理器类的上面,用于创建控制器对象。控制器对象,能够接受用户提交的参数,显示请求的处理结果。
2.1.3 @Value
用于简单类型赋值
public class Student {
@Value(value="zhangsan")
private String name;
@Value(value="29")
private int age;
}
2.1.4 @Autowired
给引用类型进行赋值,使用的是自动注入原理。默认使用的是byType自动注入。
(1)默认优先按照类型去容器中找对应的组件:
applicationContext.getBean(BookDao.class)
(2) 当容器中有多个相同类型的component,再将属性的名称作为组件的id去容器中查找
applicationContext.getBean(“bookDao”)
Autowired注解有一个requried属性,boolean类型,默认值为true。
true:表示 应用类型赋值失败,程序报错,并终止执行。
false:应用类型赋值失败,程序正常执行,应用类型为null
byName的使用方式如下:
public class Student {
@Autowired
@Qualifier(value="mySchool")
private School school;
}
2.1.5 @Resource
来自jdk的注解,Spring提供对这个注解功能的支持。@Resource可以用来给引用类型进行赋值,使用的也是自动注入原理,默认是byName方式。
优先使用byName,如果byName失败,再使用byType方式进行赋值。
不支持@Primary
public class Student {
@Resource
private School school;
}
public class Student {
// 只使用byName方式
@Resource(name="bean的id")
private School school;
}
2.1.6 @Inject
和 @Autowited的功能一样。 没有(required=false)功能
2.1.7 注解方式给容器中注册组件小结
/**
* 给容器中注册组件;
* 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
* 2)、@Bean[导入的第三方包里面的组件]
* 3)、@Import[快速给容器中导入一个组件]
* 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
* 2)、ImportSelector:返回需要导入的组件的全类名数组;
* 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
* 4)、使用Spring提供的 FactoryBean(工厂Bean);
* 1)、默认获取到的是工厂bean调用getObject创建的对象
* 2)、要获取工厂Bean本身,我们需要给id前面加一个&
* &colorFactoryBean
*/
2.2 XML方式
2.2.1 set注入
(1) 简单类型的注入
Spring规定:java中基本数据类型和String类型为简单类型
<bean id = "xxx" class="yyyy">
<property name="属性名称" value="属性值" />
<property name="" value="" />
</bean>
(2)引用类型的注入
<bean id = "xxx" class="yyyy">
<property name="属性名称" ref="bean的id" />
<property name="" ref="" />
</bean>
2.2.2 构造注入
<bean id = "xxx" class="yyyy">
<constructor-arg name="属性名称" value="属性值" />
<constructor-arg name="属性名称" ref="bean的id" />
</bean>
<bean id = "xxx" class="yyyy">
<constructor-arg index="参数列表中的index" value="属性值" />
<constructor-arg index="参数列表中的index" ref="bean的id" />
</bean>
2.2.3 自动注入
【byName】
java类中引用类型的属性名和配置文件中的id是一样的,并且数据类型也是一致的,这样就可以完成自动注入。
<bean id = "xxx" class="yyyy" autowire="byName">
简单类型属性赋值
</bean>
【byType】
引用类型的数据类型和的class属性是同源关系( 数据类型和bean的class是一样的、父子类关系或者接口实现关系)的,这样的bean能够赋值给引用类型。
<bean id = "xxx" class="yyyy" autowire="byType">
简单类型属性赋值
</bean>
注意:当有多个同源的类满足的时候,是错误的,Spring要求满足条件的类具有唯一性。
2.3 XML方式和注解方式的比较
注解为主,配置为辅
注解:可读性好,但是有侵入性
配置:可读性不好,但是解耦比较好。
经常修改的用配置,不怎么该的就用注解。