IOC:
1,简介:
IOC(Inversion of Control 即控制反转)将对象交给容器管理
- 谁控制了谁?是容器控制了对象
- 控制什么?主要控制了外部资源及生命周期
- 由容器帮我们查找并注入依赖的对象,对象只能被动的接收依赖对象,依赖对象的获取被反转了
spring中提供了一种IOC容器,来控制对象的创建,无论是你创建对象,处理对象之间的依赖关系,对象的创建时间还是对象的创建数量,都是spring提供IOC容器上配置对象的信息就可以了
2,作用:
- 由IOC容器帮对象找相应的依赖思想并注入,并不是由对象主动去找
- 资源集中管理,实现资源的可配置和易管理
- 降低了使用资源双方的依赖程度,松耦合
3,Spring容器管理对象:
第一步:maven管理依赖:引入spring核心依赖
<properties>
<spring.propety>4.1.7.RELEASE</spring.propety>
</properties>
<dependencies>
<!--spring核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.propety}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.propety}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.propety}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.propety}</version>
</dependency>
</dependencies>
第二步:给定容器配置文件:
根标签:
<?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>
第三步:IOC容器管理对象:
将userInfo对象交给容器管理:
<!--使用bean标签来管理对象,id属性必填,用来表示对象,class属性给定对象的全限定名-->
<bean id="UserInfo" class="xwbspring.Spring.IOC.ObjectUse.UserInfo"/>
第四步:通过容器获取对象
public class IocContest {
public static void main(String[] args) {
//获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Springcontest.xml");
//获取对象
UserInfo userInfo = (UserInfo) context.getBean("UserInfo");
//getBean():传入的参数必须与XML配置的id相同
System.out.println(userInfo);
}
}
运行截图:
4,Spring中Bean的实例化方式
方法一:基于xml配置形式
<1,通过无参构造实例化:如3中的例子
<2,,通过静态功能方式实例化:
1,创建一个工厂类:
2,使用工厂的静态方法返回去一个对象:
public class ObjectFactory {
//静态方法:
public static UserInfo getBean(){
return new UserInfo();
}
}
3,配置XML文件:
<!--
通过静态工厂获取对象
id属性是给静态工厂获取的对象进行命名
class属性指向工厂类全限定名
factory-method属性是工厂类中获取对象的静态方法
-->
<bean id="UserInfo1" class="xwbspring.Spring.IOC.IOCDemo.ObjectFactory" factory-method="getBean"/>
❤️,通过普通工厂实例化
1,创建一个工厂类:
2,使用工厂的普通方法返回一个对象:
public class ObjectFactory {
//普通方法:
public UserInfo getUserInfo(){
return new UserInfo();
}
}
3,配置XML文件:
<!--通过普通工厂获取对象 -->
<bean id="factory" class="xwbspring.Spring.IOC.IOCDemo.ObjectFactory"/>
<!--创建工厂对象-->
<bean id="userInfo2" class="xwbspring.Spring.IOC.ObjectUse.UserInfo" factory-bean="factory" factory-method="getUserInfo"/>
方法二:基于注解形式:
1,通过Component注解标记类
@Component(value = "userInfo")
//注解形式类似于配置中bean标签处理, 注解中value参数和bean标签中id是相同的作用
public class UserInfo {
private String name;
private String sex;
//todo
}
2,配置XML文件
<!--根标签,注解形式与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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描,指定的包路径或者类名:扫描类、方法、属性上是否有注解-->
<context:component-scan base-package="xwbspring.Spring.IOC.ObjectUse"/>
</beans>
常见注解:
@Component
@Controller 对Controller层类进行标注(主要接受处理URL)
@Service 对Service层的类进行标注(是进行业务处理)
@Repository 对DAO层实现类进行标注(和数据库打交道的类)
后三个都是Component注解衍生出来,功能是一样,可以互换,为了区分被注解标注的类在不同的业务层,是逻辑更清晰
IOC中属性讲解:
Bean的作用范围@Scope:其@Scope取值可以为singleton:单例对象,默认是单例prototype:多例对象
5,Spring中DI介绍
DI-Dependency Injection:依赖注入
bean对象中需要依赖一些其他组件或者对象,依赖关系由容器在运行时决定
两种方式处理依赖注入:
基于配置形式:
1,有参构造函数注入依赖:
public class User {
private String name;
private UserInfo userInfo;
public User(String name,UserInfo userInfo) {
this.name = name;
this.userInfo = userInfo;
}
相关的XML配置:
<bean id="user" class="xwbspring.Spring.IOC.ObjectUse">
<!--
通过有参构造函数实例
constructor-arg:有参构造使用改标签
name属性:表示是属性名
value属性:属性赋值,给定字符串参数,给基本引用类型/基本类型赋值
ref属性:属性赋值,给自定义对象赋值
-->
<constructor-arg name="userInfo" ref="userInfo"/>
<constructor-arg name="name" value="xwb"/>
</bean>
2,set方法:
public class User {
private String name;
public void setName(String name) {
this.name = name;
}
}
相关的XML配置:
<bean id="user1" class="xwbspring.Spring.IOC.ObjectUse">
<property name="name" value="hello"/>
</bean>
基于注解形式
@Component
public class User {
@Value("tulun") //针对普通类型(String,int等)的数据
private String name;
@Autowired //注入自定义对象类型
@Resource //注入自定义对象类型
private UserInfo userInfo;
循环依赖的问题:
如果是使用构造函数的方式注入依赖,有可能会无法解决循环依赖的问题
解决办法:
对于会产生循环依赖的问题的这些类可以通过setter方法注入,可以解决循环依赖
6,其他类型:
public class User {
private String name;
private UserInfo userInfo;
//list类型
private List<String> lists;
//map类型
private Map<String,String> maps;
//set类型
private Set<String> sets;
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
public void setLists(List <String> lists) {
this.lists = lists;
}
public void setMaps(Map <String, String> maps) {
this.maps = maps;
}
public void setSets(Set <String> sets) {
this.sets = sets;
}
相应的XML文件
<property name="lists" >
<!--list属性注入-->
<list >
<value>张三</value>
<value>李四</value>
</list>
</property>
<property name="maps">
<!--map类型数据注入-->
<map>
<entry key="k1" value="k11"/>
<entry key="k2" value="k22"/>
</map>
</property>
<property name="sets">
<!--set类型数据注入-->
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>