Spring框架
Spring 容器创建对象的方式
接上简述一 :
https://blog.csdn.net/kaema/article/details/121622097
(注:案例中的代码都是沿用简述一的代码,若有兴趣可以点击上面的链接查看)
一已经说过使用默认的构造方法创建对象,接下来就是使用其他方法创建对象
在实体类 Student 中添加带参数的构造方法:
public Student(Integer id, String name, String classRoom) {
this.id = id;
this.name = name;
this.classRoom = classRoom;
}
创建工厂类:
package com.imok.pojo;
public class Factory {
/**
* 实例方法
*/
public Student instanceFun(){
System.out.println("Factory--------instanceFun");
return new Student(1,"小白","三班");
}
/**
* 静态方法
*/
public static Student staticFun(){
System.out.println("Factory---------staticFun");
return new Student(2,"小黑","四班");
}
}
由于怕麻烦就放在pojo包下了…
创建新的配置文件 createType.xml:
通过默认构造方法创建
<!--1、通过默认构造方法-->
<bean id="student1" class="com.imok.pojo.Student"></bean>
通过带参数的构造方法创建
<!--2、通过带参数的构造方法-->
<bean id="student2" class="com.imok.pojo.Student">
<!--name:表示参数的名称-->
<constructor-arg name="id" value="7"/>
<constructor-arg name="name" value="圣枪哥"/>
<constructor-arg name="classRoom" value="EDG"/>
</bean>
<!--通过下标索引创建带参构造方法-->
<bean id="student3" class="com.imok.pojo.Student">
<!--index:表示参数的下标索引-->
<constructor-arg index="0" value="9"/>
<constructor-arg index="1" value="路飞"/>
<constructor-arg index="2" value="草帽海贼团"/>
</bean>
通过工厂方法创建:
<!--静态方法
相当于:Student student4 = Factory.staticFun();-->
<bean id="staticStudent" class="com.imok.pojo.Factory" factory-method="staticFun"></bean>
<!--实例方法 相当于先new对象后调用对象的方法
Factory factory = new Factory();
Student instanceStudent = factory.instanceFun();-->
<bean id="factory" class="com.imok.pojo.Factory"></bean>
<bean id="instanceStudent" factory-bean="factory" factory-method="instanceFun"></bean>
测试类:
package com.imok.pojo;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CreateTypeTest {
@Test
public void test01(){
ApplicationContext ac = new ClassPathXmlApplicationContext("createType.xml");
}
}
测试执行结果:
基于XML的DI
DI-Dependency Injection,即依赖注入;是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台
通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关系具体的资源来自何处,由谁实现
IoC是一个概念,其实现方式多种多样,依赖注入就是其中用的比较多的一种方式
IoC 和 DI 是同一个概念的不同角度描述,IoC 是一种思想,概念,DI 是实现它的手段。Spring 框架使用依赖注入实现 IoC
注入分类
bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化就是由容器自动完成的,称为注入
通过set方法
set 注入也叫设值注入,指通过 setter 方法传入被调用者的实例,这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用
自动注入
对于引用类型属性的注入,也可不在配置文件中显示的注入,可以通过设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性),根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType:根据类型自动注入
1、byName
当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用 byName 方式,让容器自动将被调用者 bean 注入给调用者 bean,容器是通过调用者的 bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的
2、byType
使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 bean 类的某引用类型属性类型同源,即要么相同,要么有 is-a 关系(子类,实现类),但使用该方式同源被调用的 bean 只能有一个,多于一个容器就不知道该匹配哪个了。
示例:
创建 StudentDao.java
package com.imok.dao;
public class StudentDao{
public void add(){
System.out.println("Student --- add ---");
}
}
创建 StudentService.java
package com.imok.service;
import com.imok.dao.StudentDao;
public class StudentService{
private StudentDao studentDao;
public void add(){
studentDao.add();
System.out.println("StudentService ---- add ----");
}
public StudentService(){}
public StudentService(StudentDao studentDao){
this.studentDao= studentDao;
}
public void setStudentDao(StudentDao studentDao){
this.studentDao= studentDao;
}
public StudentDao getStudentDao(){
return studentDao;
}
}
创建配置文件 DI.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.xsd">
<bean id="studentDao" class="com.imok.dao.StudentDao"></bean>
<bean id="studentService1" class="com.imok.service.studentService">
<!--使用set方法注入属性值-->
<property name="studentDao" ref="studentDao"></property>
</bean>
<bean id="studentService2" class="com.imok.service.StudentService">
<!--使用构造方法注入属性值-->
<constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
</bean>
<!--按名称自动注入:寻找容器中id名和属性名一直的对象进行注入-->
<bean id="studentService3" class="com.imok.service.StudentService" autowire="byName"></bean>
<!--按类型自动注入:寻找容器中类型与属性类型相同或者符合is-a关系的对象进行注入,但是要求类型相同的对象唯一,否则抛出异常-->
<bean id="studentService4" class="com.imok.service.StudentService" autowire="byType"></bean>
</beans>
创建测试类:
package com.imok.pojo;
import com.imok.dao.StudentDao;
import com.imok.service.StudentService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test02{
@Test
public void test02(){
ApplicationContext ac = new ClassPathXmlApplicationContext("DI.xml");
StudentService studentService1 = (StudentService) ac.getBean("studentService1");
studentService.add();
StudentService studentService2 = (StudentService) ac.getBean("studentService2");
studentService2.add();
StudentService studentService3 = (StudentService) ac.getBean("studentService3");
studentService3.add();
StudentService studentService4 = (StudentService) ac.getBean("studentService4");
studentService4.add();
}
@Test
public void test01(){
StudentDao studentDao = new StudentDao();
StudentService studentService = new StudentService();
studentService.setStudentDao(studentDao);
studentService.add();
}
}
test01的执行结果:
test02的执行结果:
各种注入方式都可以使用,视具体情况而定