Spring-IOC容器XML实现对象的实例化 -- 02
目录
IOC
本章介绍了控制反转(IoC)原理的Spring框架实现。
IoC也称为依赖注入(DI)。在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建bean时注入那些依赖项。从本质上讲,此过程是通过使用类的直接构造或诸如服务定位器模式之类的机制来控制其依赖关系的实例化或位置的Bean本身的逆过程(因此,其名称为Control Inversion)。
DI是IOC的一种实现形式
Pom.xml文件 (maven的依赖内容)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-01-ioc</artifactId>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.6</version>
</dependency>
</dependencies>
</project>
Bean
实例化对象
xml实例化对象可以理解为,在系统初始化的的时候就把配置文件里的bean都给实例化完毕了。并且默认使用的是单例模式,保证每一个bean对象只有一个实例。如果需要一个对象实例化多个不同的实例,可以手动把单例模式改成原型模式就可以了。
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
实例化具体对象的xml配置文件
在标准的xml里加入<bean id="唯一标识id,使用ref调用" class="指向具体的类"/>标签即可
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用spring来创建对象,在spring这些都称为Bean-->
<!--注入Dao-->
<bean id="mysqlDaoImpl" class="com.kuang.dao.mysqlDao"/>
<bean id="sqlservDaoImpl" class="com.kuang.dao.sqlservDao"/>
<bean id="oracleDaoImpl" class="com.kuang.dao.oracle"/>
</beans>
代码架构
具体代码
dao
package com.kuang.dao;
/**
* @program: spring
* @description: 测试dao
* @author: 康世行
* @create: 2021-04-22 10:59
*/
public interface UserDao {
//获取信息
void getInforim();
}
package com.kuang.dao;
/**
* @program: spring
* @description: mysql实现测试
* @author: 康世行
* @create: 2021-04-22 11:01
*/
public class mysqlDao implements UserDao {
@Override
public void getInforim() {
System.out.println("mysql实现");
}
}
package com.kuang.dao;
/**
* @program: spring
* @description: 测试
* @author: 康世行
* @create: 2021-04-22 11:17
*/
public class oracle implements UserDao {
@Override
public void getInforim() {
System.out.println("oracle实现");
}
}
package com.kuang.dao;
/**
* @program: spring
* @description: sqlerver实现
* @author: 康世行
* @create: 2021-04-22 11:01
*/
public class sqlservDao implements UserDao {
@Override
public void getInforim() {
System.out.println("sqlerver实现");
}
}
service
package com.kuang.service;
/**
* @program: spring
* @description: service测试
* @author: 康世行
* @create: 2021-04-22 11:02
*/
public interface UserService {
//获取user信息
void getUer();
}
package com.kuang.service;
import com.kuang.dao.UserDao;
import com.kuang.dao.mysqlDao;
import com.kuang.dao.sqlservDao;
/**
* @program: spring
* @description: userService实现类
* @author: 康世行
* @create: 2021-04-22 11:04
*/
public class UserServiceImpl implements UserService{
//注入dao依赖
//private UserDao userDao=new sqlservDao();
private UserDao userDao;
//实现动态创建对象,不用提前把对象写死,根据客户端的需求去实例化对您的对象。
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUer() {
userDao.getInforim();
}
}
test
import com.kuang.dao.mysqlDao;
import com.kuang.dao.oracle;
import com.kuang.dao.sqlservDao;
import com.kuang.service.UserService;
import com.kuang.service.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @program: spring
* @description: 测试程序
* @author: 康世行
* @create: 2021-04-22 11:06
*/
public class MyTest {
public static void main(String[] args) {
//设置上下文环境对象,用与获得指定的对象。(拿到spring容器)
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
//获取指定对象
UserService userServiceImpl = (UserServiceImpl) applicationContext.getBean("UserServiceImpl");
userServiceImpl.getUer();
}
}
注入属性(手动)
注入属性配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用spring来创建对象,在spring这些都称为Bean-->
<!--注入Dao-->
<bean id="mysqlDaoImpl" class="com.kuang.dao.mysqlDao"/>
<bean id="sqlservDaoImpl" class="com.kuang.dao.sqlservDao"/>
<bean id="oracleDaoImpl" class="com.kuang.dao.oracle"/>
<!--注入Service-->
<bean id="UserServiceImpl" class="com.kuang.service.UserServiceImpl">
<!--注入具体的属性 -->
<property name="userDao" ref="sqlservDaoImpl"/>
</bean>
</beans>
可以随时切换红圈里的ref值,进行替换具体的实现类。
注入属性(Autowired自动)
xml自动转配类型:
autowire="byName"
autowire="byType"
一共两种:
第一种是根据下面set方式的后半部分的名字去和配置文件里的bean对象id进行匹配,如下图setsqlservDAO的后半部分 sqlservDAO必须和bean id一致 id="sqlservDAO"
通过名字进行自动注入
第二种是根据不同的类去进行匹配,就是根据类型进行匹配。
比较推荐第一种,根据不同的名字去匹配方便一个类对应多个对象。而第二种如果出现一个类对应多个对象,就会装配失败因为多个对象
都是同一个类型的所以无法区分到底装配那个对象。
把上面的例子改造成自动装配,不只是改上面的xml配置文件里的内容。这个自动装配实例是以byName为例的,所以配置文件大家可以使用上面byName部分的xml配置文件
还需要更改service部分的实现类代码
package com.kuang.service;
import com.kuang.dao.UserDao;
import com.kuang.dao.mysqlDao;
import com.kuang.dao.sqlservDao;
/**
* @program: spring
* @description: userService实现类
* @author: 康世行
* @create: 2021-04-22 11:04
*/
public class UserServiceImpl implements UserService{
//注入dao依赖
//private UserDao userDao=new sqlservDao();
private sqlservDao sqlservDao;
public void setSqlservDao(com.kuang.dao.sqlservDao sqlservDao) {
this.sqlservDao = sqlservDao;
}
//实现动态创建对象,不用提前把对象写死,根据客户端的需求去实例化对您的对象。
@Override
public void getUer() {
sqlservDao.getInforim();
}
}
大家可以看出来注入的字段,把原来的接口换成了具体的实现类。 (这种自动注入确实不太好,我相信大多数小伙伴已经看出来。这个如果增加子类的话还得更改service实现类,不符合开闭原则)
具体适不适合,符不符合还得结合实际的业务需求。
测试结果
其实xml的注入还是基于set方法实现的 Set注入基本案例