一、IOC介绍
IOC(Inversion Of Control) 控制反转,spring中提供了IOC容器
对象的创建交给外部容器完成,这个就是控制反转
spring中使用控制反转来实现对象在不同程序中的使用
容器存在的必要性就是管理对象
二、IOC思想
-
对象的创建交给外部容器完成,这个就是控制反转
-
spring中使用控制反转来实现对象在不同程序中的使用
控制反转解决对象处理的问题,将对象交给容器进行创建 -
依赖注入(DI):dendendency injection
-
对象与对象之间的依赖问题即依赖注入 AOP->DI
Spring使用依赖注入来实现对象之间的依赖关系
在对象创建之后,对象的关系处理就是依赖注入 -
无论对象的创建,处理对象之间的依赖关系,对象创建的时间还有对象创建的数量,都可以在spring的IOC容器上配置对象的信息就好了
三、Spring管理
1.Spring引入依赖
<!--spring的核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>
3.创建实体类
创建需要容器管理的类
public class User {
private Integer id;
private String name;
}
将user对象交给容器管理
<!--使用bean标签类管理对象 id:属性标识对象,不可重复 class属性代表要管理的对象的全路径-->
<bean id="user" class="com.tulun.bean.User"/>
4.通过容器来获取User对象
//获取IOC容器,通过读取classpath路径下的spring的配置文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");
//在IOC容器获取需要的对象实例
User user = (User) applicationContext.getBean("user");`
原理:获取User对象时要new User() ,将对象的全路径配置在容器中,容器该如何创建对象呢?–>反射 -->IOC容器底层拿到类的全路径,然后可以通过反射的技术来创建实例
5.总结
1、创建一个spring的配置文件
2、对xml配置文件进行解析
3、BeanFactory工厂类
4、在工厂类中通过反射创建bean对象
四、Spring的IOC容器介绍
1.Spring IOC容器中接口的继承关系,
ApplicationContext是BeanFactory子接口实现之一,
BeanFactory是IOC容器定义的最底层的接口
ApplicationContext是高级实现之一,对BeanFactory的接口做了很多的扩展,大部分情况ApplicationContext使用
2.ApplicationContext接口常见的实现类
读取classpath中的资源
ClassPathXmlApplicationContext
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");
读取系统指定的资源文件
FileSystemXmlApplicationContext
FileSystemXmlApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("d://test.xml");
读取web环境下的资源文件
XmlWebApplicationContext
XmlWebApplicationContext applicationcontext = new XmlWebApplicationContext();
3.Spring IOC容器来获取bean对象的过程
五、Spring对Bean的实例化方式
1.基于配置形式
bean的实例化基于配置的方式:
通过无参构造函数实例化
<!--通过无参构造实例化bean-->
<bean id="user" class="com.tulun.bean.User" scope="singleton"/>
Spring容器对上面的类的实例化采用的是无参构造函数来实例化bean。
通过静态工厂方式实例化
1.首先创建静态工厂类获取User对象
package com.tulun.factory;
import com.tulun.bean.User;
/**
* 静态工厂类
*/
public class StaticFactory {
public static User getUser(){
return new User();
}
public static void main(String[] args) {
User user=StaticFactory.getUser();
}
}
2.Spring容器管理配置如下:
<!--通过静态工厂类获取User对象-->
<bean id="user" class="com.tulun.factory.StaticFactory" factory-method="getUser"/>
静态工厂方式获取对象是class属性工厂类的全路径,factory-method属性是指在工厂类中指定的方法来获取需要的对象。
通过普通工厂方式实例化
1.首先创建普通工厂类获取User对象
package com.tulun.factory;
import com.tulun.bean.User;
/**
普通工厂
*/
public class CommonFactory {
public User getUser(){
return new User();
}
public static void main(String[] args) {
CommonFactory commonFactory=new CommonFactory();
User user=commonFactory.getUser();
}
}
2.Spring容器配置如下:
<!--通过普通工厂类来获取-->
<!--先获取工厂实例-->
<bean id="factory" class="com.tulun.factory.CommonFactory"/>
<!--指定工厂类的方法-->
<bean id="user2" factory-bean="factory" factory-method="getUser"/>
首先需要获取工厂实例,通过普通工厂实例获取User对象时,factory-bean属性是指在工厂类中指定方法来获取需要的对象。
2.基于注解形式
基于注解形式比xml方式更加简单,开发更快
1.在配置文件中引入新的约束,且开启注解扫描
<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--开启扫描注解:指定的包路径下的类,会扫描的到类的方法,属性上-->
<context:component-scan base-package="com.tulun.bean"/>
<!--只扫描类中属性的注解(不建议使用)-->
<!--<context:annotation-config></context:annotation-config>-->
</beans>
2.在对应的类上添加注解
@Component("user")
//注解中的user=xml文件中的bean
public class User {
private Integer id;
private String name;
这里使用注解是@Component
@Component | 通用注解 |
---|---|
@Repository | 对DAO层实现类进行标注 |
@Service | 对Service层业务逻辑层进行标注 |
@Controller | 对Controller的实现类进行标注 |
四个注解可以通用,功能一样,可以互换,使用不同注解主要是区分被注解的类处在不同的业务层,使逻辑更加清晰
六、Spring中依赖注入
bean的实例化说明的是IOC的问题,创建对象之后对象中的属性如何负值问题,即依赖注入问题(DI)
1.xml配置方式依赖注入
通过有参构造
1.user类中的有参函数
public class User {
private Integer id;
private String name;
/**
* 有参构造函数
* @return
*/
public User(){}
public User(Integer id,String name){
this.id=id;
this.name=name;
}
}
2.spring容器配置
<!--依赖注入:有参构造函数-->
<bean id="user3" class="com.tulun.bean.User">
<!--
注入属性
name属性:给定类的属性名称
value属性:对指定属性名称赋值 ,直接获取的是String类型的值
ref属性:对指定属性进行赋值 指定的是一个容器管理的对象
-->
<constructor-arg name="id" value="5" />
<constructor-arg name="name" value="zzzzz"/>
</bean>
通过有参构造函数完成依赖注入时,使用constructor-arg标签进行属性赋值
2.注解形式依赖注入
1.在user类中需要由setter方法
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
2.spring容器的配置
<!--依赖注入:setter方式-->
<bean id="user4" class="com.tulun.bean.User">
<!--属性注入-->
<property name="id" value="3"/>
<property name="name" value="ccccccc"/>
</bean>
setter方式的依赖注入:使用property标签进行赋值
3.自定义类型
自定义类型无论是ser方法还是有参构造均可,但是对于自定义类型赋值时要使用的时ref
4.注入集合类型
注入集合类型、:数组、Set、List、Map的个形式集合都可以注入
基于xml形式注入
以map集合为例进行注入
1.在user类中声明
public class User {
private Integer id;
private String name;
private Map<String,String >map;
}
2.spring容器中的配置
<!--map集合类型-->
<bean id="user5" class="com.tulun.bean.User">
<!--属性注入-->
<property name="id" value="3"/>
<property name="name" value="sssss"/>
<property name="map" >
<map >
<entry key="1" value="z"></entry>
<entry key="2" value="c"></entry>
<entry key="3" value="33"></entry>
</map>
</property>
</bean>
基于注解形式
@Value | 注入普通类型属性 |
---|---|
@Resource | 注入对象类型 |
@Autowired | 注入对象类型,默认是按照类型注解 |
1.user类
public class User {
@Value("5")
private Integer id;
@Value("ll")
private String name;
}
依赖的注入都是在类的属性上。
注解@Resource和@Autowired的区别
Spring中,@Resource和@Autowired都是做bean的注入时使用的,使用过程中,有时候@Resource和@Autowired可以相互替换,有时候不可以。
共同点:
@Resource和@Autowired都可以作为注入属性的修饰,在接口仅有单一实现类时,两个注解的修饰效果相同,不影响使用。
不同点:
@Resource时java自己的注解,它有两个属性时比较重要的,分别是name和type。
spring将@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。所以如果使用name属性,则使用byName自动注入策略,而是用type属性是则使用byType自动注入策略,如果既不指定name也不指定type属性,这是将通过反射机制使用byName自动注入策略。
@Autowired是spring的注解,是spring2.5版本引入的,@Autowired只根据type进行注入,不会去匹配name,如果涉及到type无法辨别注入对象时,则需要依赖@Qualifier或 @Primary注解来一起修饰。
Spring框架里面两个注解都可以使用,非Spring框架中只能使用@Resource注解。