提示:以下是本篇文章正文内容,下面案例可供参考
一、IOC和DI的关系
IOC:(Inverse of Control 反转控制), 将对象创建权利交给Spring工厂进行管理。是一种思想。
DI:(Dependency Injection 依赖注入),是指spring框架在创建bean对象时,动态地将依赖对象注入到bean组件中,是实现ioc思想的一个动作。
二、以配置xml的方式创建bean
创建spring的核心配置文件
一般我们将spring的核心配置文件命名为applicationContext.xml(.xml是文件后缀名),当然可以随意命名。
下面是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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 在这里写配置-->
<!-- 在这里写配置-->
<!-- 在这里写配置-->
</beans>
在pom.xml中添加依赖(jar包)
这是spring的核心依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
创建两个pojo:Son Father
public class Father {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Father(){
System.out.println("Father放入ioc中");
}
@Override
public String toString() {
return "Father{" +
"name='" + name + '\'' +
'}';
}
}
public class Son {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Son() {
System.out.println("Son放入ioc容器中");
}
@Override
public String toString() {
return "son{" +
"name='" + name + '\'' +
'}';
}
}
告诉ioc容器,将son类和father放入容器中
在applicationContext.xml中写入
<!-- class是这个类所在的包的位置-->
<bean id="son" class="pojo.Son"></bean>
<bean id="father" class="pojo.Father"></bean>
测试
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
// 这里的字符串"applicationContext.xml"要与核心配置文件的名称相同,否则会有空指针异常;
Son son=(Son)app.getBean("son");//getBean里的字符串要与配置文件中的id相同,否则,spring会找不到bean
//从ioc容器中得到son对象,返回值是Object,强转为son
//Father同理
Father father=(Father)app.getBean("father");
System.out.println(son);
System.out.println(father);
}
结果
Son放入ioc容器中
Father放入ioc中
son{name=‘null’}
Father{name=‘null’}
可以看到,两个类的构造函数执行了,就是说,spring加载的时候,两个类的对象就创建好并放入了容器中。
注解的方式创建bean
加注解
@Component("son")//这里同样要和getBean中的名称保持一致
public class Son {
@Component("father")//同上
public class Father {
进行包扫描
<!-- class是这个类所在的包的位置-->
<!-- <bean id="son" class="pojo.Son"></bean>-->
<!-- <bean id="father" class="pojo.Father"></bean>-->
<context:component-scan base-package="pojo"></context:component-scan>
结果
Father放入ioc中
Son放入ioc容器中
son{name=‘null’}
Father{name=‘null’}
两者各有优点,配置文件的方式,降低了代码的耦合度,注解方式增加了代码的可读性。
DI(依赖注入)
创建两个类
public class UserService {
public void say(){
System.out.println("UserService被使用了!");
}
}
public class UserController {
private UserService userService;
public void say(){
userService.say();
}
}
可以看到UserController用到了UserService的方法。
加上注解,交给spring管理
@Controller("UserController")
public class UserController {
@Service("UserService")
public class UserService {
这个时候是会报空指针异常,因为虽然两个类都实例化并交给spring管理,但是我们可以看到在UserController中
@Controller
public class UserController {
//这个UserService 是没有实例化的,换句话说,
//这个userService不是spring管理的那个userService,
//这个时候,
//我们需要使用spring中的userService,就需要依赖注入
private UserService userService;
public void say(){
userService.say();
}
}
set注入(配置文件形式)
UserController中加入set方法
@Controller("UserController")
public class UserController {
private UserService userService;
public void setUserService(UserService userService){
this.userService=userService;
}
public void say(){
userService.say();
}
}
在配置(applicationContext.xml)文件中
<bean id="UserService" class="pojo.UserService"></bean>
<bean id="UserController" class="pojo.UserController">
<property name="userService" ref="UserService"></property>
<!-- 这里的name 是set方法的名称,去掉set后,再将首字母小写 -->
<!-- ref就是 要注入的bean的id-->
</bean>
结果
UserService被使用了!
正常
set注入(注解方式)
在Usercontroller中 酱紫写就可以了,加上Autowired(别忘了在配置文件中加上包扫描)
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService=userService;
}
构造方法注入(配置文件形式)
private UserService userService;
public UserController(UserService userService){
this.userService=userService;
}
<bean id="UserService" class="pojo.UserService"></bean>
<bean id="UserController" class="pojo.UserController">
<constructor-arg name="userService" ref="UserService"></constructor-arg>
<!--这里的name 是构造方法中的参数名-->
</bean>
构造方法注入(注解形式)
private UserService userService;
@AutoWired
public UserController(UserService userService){
this.userService=userService;
}
普通、集合数据类型注入
不仅仅是对象可以注入,普通数据类型 集合数据类型也可以注入
这里我们之说set注入的配置形式和注解形式,构造形式的与set类似
普通数据类型注入(配置文件形式)
son类
@Component("son")
public class Son {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Son{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<bean id="son" class="pojo.Son">
<property name="name" value="zhangsan"></property>
<property name="age" value="1"></property>
</bean>
结果
Son{name=‘zhangsan’, age=1}
普通数据类型注入(注解形式)
public class Son {
@Value("lisi")
private String name;
@Value("3")
private int age;
结果
Son{name=‘lisi’, age=3}
集合类型注入(配置形式)
list里面放普通数据
public class Father {
private List<String> list;
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
<bean id="father" class="pojo.Father">
<property name="list" >
<list>
<value>aaa</value>
<value>bbb</value>
</list>
</property>
</bean>
结果
Father{list=[aaa, bbb]}
list里放引用类型
<bean id="father" class="pojo.Father">
<property name="list" >
<list>
<bean id="son1" class="pojo.Son">
<property name="name" value="zhangsan"></property>
<property name="age" value="1"></property>
</bean>
<bean id="son2" class="pojo.Son">
<property name="name" value="lisi"></property>
<property name="age" value="2"></property>
</bean>
</list>
</property>
</bean>
结果
Father{list=[Son{name=‘zhangsan’, age=1}, Son{name=‘lisi’, age=2}]}
map放引用类型+普通类型
private Map<String,Son> map;
public Map<String, Son> getMap() {
return map;
}
<bean id="son1" class="pojo.Son">
<property name="name" value="zhangsan"></property>
<property name="age" value="1"></property>
</bean>
<bean id="son2" class="pojo.Son">
<property name="name" value="lisi"></property>
<property name="age" value="2"></property>
</bean>
<bean id="father" class="pojo.Father">
<property name="map">
<map>
<entry key="one" value-ref="son1"></entry>
<entry key="two" value-ref="son2"></entry>
</map>
</property>
</bean>