Spring IOC
一、介绍
1、IOC(Inversion of Control)。
控制反转IOC(Inversion of Control)和依赖注入DI(Dependency Injection)是同一个概念,IOC是目的,DI是方法手段。通常由调用者创建被调用者的实例,但spring中创建被调用者的实例由spring完成,然后注入调用者。
2、容器。
Spring 容器是 Spring 框架的核心,是用来管理对象的,用Map来存储。在java项目中的实现org.springframework.context.ApplicationContext接口的类的实例,或者在xml配置文件中进行配置。一个Spring容器就是某个实现了ApplicationContext接口的类的实例。
Spring容器基本分为两种,一个是ApplicationContext(继承BeanFactory),一个是BeanFactory,其中BeanFactory只提供基本的DI功能。因为Spring容器是基于ICO进行控制对象的,所以也称为ICO容器。
3、注入方式。
1)、配置注入(Xml)。配置注入分为set注入和构造注入,分别对应对象中的属性和构造方法。
2)、配置注入(Java)。就是用java代码来实现xml配置的实现。要使用到注解@ Configuration和@Bean来实现。
3)、注解注入。先需要在xml配置文件或者java启动类上声明扫描的包。然后在被引入类上要声明注解:
@Component,无明确的。
@Controller,控制层(controller)。
@Service,业务逻辑层(service)。
@Repository,数据访问层(dao)。 最后在引入地方的字段上面使用注解@Autowire或者@Resource进行注入,基
本类型字段的注入使用@Value注解。
4、注解@Autowire和@Resource的区别。
对比项 @Autowire @Resource
注解来源 Spring注解 JDK注解(JSR-250标准注解,属于J2EE)
装配方式 优先按类型 优先按名称
属性 required name、type
Resoure的装配顺序
如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
如果指定name属性,则按照名称(by-name)装配,未找到则抛异常;
如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常;
既未指定name属性,又未指定type属性,则按照名称(by-name)装配;如果未找到,则按照类型(by-type)装配。
二、配置注入(Xml)
1、在main包下新建resource文件夹,然后在其上面点击右键,将其改为资源路径。
2、在resource下面新建spring.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">
<bean id="userServiceByXml" class="com.zxj.dao.service.impl.UserServiceImpl"/>
<!--set注入-->
<bean id="userByXml" class="com.zxj.dao.entity.User">
<property name="name" value="set注入"/>
<property name="age" value="12"/>
</bean>
<!--构造注入-->
<bean id="userByXml2" class="com.zxj.dao.entity.User">
<constructor-arg name="name" value="构造注入"/>
<constructor-arg name="age" value="23"/>
</bean>
</beans>
3、新建User.java、IUserService.java、UserServiceImpl.java。
package com.zxj.dao.entity;
public class User {
private String name;
private int age;
public User(){
}
public User(String name, int age) {
this.name = name;
this.age = 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;
}
}
package com.zxj.dao.service;
import com.zxj.dao.entity.User;
public interface IUserService {
void printInfo(User user);
}
package com.zxj.dao.service.impl;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;
public class UserServiceImpl implements IUserService {
@Override
public void printInfo(User user) {
System.out.println(String.format("%s已经%d岁了", user.getName(), user.getAge()));
}
}
4、测试单元测试。
package com.zxj;
import com.zxj.dao.entity.Book;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IBookService;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
@Test
public void iocTest1() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
User user = new User();
user.setAge(10);
user.setName("卓小杰");
System.out.println("通过名字,获取bean对象: ");
IUserService userService = (UserServiceImpl) ac.getBean("userService");
userService.printInfo(user);
System.out.println("通过类型,获取bean对象: ");
IUserService userService2 = ac.getBean(UserServiceImpl.class);
userService2.printInfo(user);
}
}
5、结果。
三、配置注入(Java)
1、新建JavaBeanConfig.java。
package com.zxj.config;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JavaBeanConfig {
@Bean("userServiceByConfig")
public IUserService userServiceByConfig() {
return new UserServiceImpl();
}
@Bean("userByConfig")
public User userByConfig() {
User user = new User();
user.setName("卓小杰");
user.setAge(16);
return user;
}
}
3、在spring.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="com.zxj"/>
</beans>
4、测试单元测试。
package com.zxj;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
/**
* aaa@qq.com和@Resource的对比
* 对比项 @Autowire @Resource
* 注解来源 Spring注解 JDK注解(JSR-250标准注解,属于J2EE)
* 装配方式 优先按类型 优先按名称
* 属性 required name、type
* <p>
* aaa@qq.com的装配顺序
* 如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
* 如果指定name属性,则按照名称(by-name)装配,未找到则抛异常;
* 如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常;
* 既未指定name属性,又未指定type属性,则按照名称(by-name)装配;如果未找到,则按照类型(by-type)装配。
*/
@Autowired
@Qualifier("userServiceByConfig")
private IUserService userServiceByConfig;
@Resource(name = "userByConfig")
private User userByConfig;
@Test
public void iocTest2() {
userServiceByConfig.printInfo(userByConfig);
}
}
5、结果。
四、注解注入
1、在spring.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="com.zxj"/>
</beans>
2、新建Book.java、IBookService.java、BookServiceImpl.java。
package com.zxj.dao.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Book {
@Value("基督山伯爵")
private String name;
@Value(value = "24.8")
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
package com.zxj.dao.service.impl;
import com.zxj.dao.entity.Book;
import com.zxj.dao.service.IBookService;
import org.springframework.stereotype.Service;
@Service("bookService")
public class BookServiceImpl implements IBookService {
@Override
public void printInfo(Book book) {
System.out.println(String.format("%s的价格是%f", book.getName(), book.getPrice()));
}
}
package com.zxj.dao.service;
import com.zxj.dao.entity.Book;
public interface IBookService {
void printInfo(Book book);
}
3、测试单元测试。
package com.zxj;
import com.zxj.dao.entity.Book;
import com.zxj.dao.entity.User;
import com.zxj.dao.service.IBookService;
import com.zxj.dao.service.IUserService;
import com.zxj.dao.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
//junit测试单元要使用下面两个注解,否则@Autowwire为null
@RunWith(SpringJUnit4ClassRunner.class)//可能会报junit版本过低的错误,将其变高就可以了
@ContextConfiguration("classpath:spring.xml")
public class AppTest {
@Autowired
private IBookService bookService;
@Autowired
private Book book;
@Test
public void iocTest3() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
Book book2 = new Book();
book2.setName("悲惨世界");
book2.setPrice(32.5);
System.out.println("通过new,获取实体对象");
bookService.printInfo(book2);
System.out.println("通过@Component和@Value,获取实体对象: ");
bookService.printInfo(book);
}
}
4、结果。
上一篇: Ubuntu系统安装dlib(C++与python)
下一篇: Spring IOC控制反转