spring框架–IOC
spring框架是一个容器,容器中存放了Java对象。IOC全名叫做控制反转,意思是将对象的创建,控制,依赖关系交给spring框架进行处理。再企业级开发中,可以降低开发的难度,减少代码的耦合度。
spring框架代码初体验
1.创建一个学生类Student
package com.service;
public class Student {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.配置spring配置文件,创建学生类
<?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="student" class="com.service.Student">
<property name="name" value="梁子祥" />
<property name="age" value="21" />
</bean>
</beans>
3.进行测试,从容器中取出对象,applicationContext表示的是容器
package com;
import com.service.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class myTest {
//使用spring容器创建的对象
@Test
public void test02(){
//1.指定spring配置文件的名称
String config = "applicationContext.xml";
//2.创建表示spring容器的对象,ApplicationContext就是表示spring容器
//ClassPathXmlApplicationContext表示从类路径开始编译文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
Student student = applicationContext.getBean("student", Student.class);
System.out.println(student);
}
}
DI(属性注入)
DI属性注入的底层原理是通过反射机制调用类的set方法,通过set方法对类的属性进行复制,因此set方法是必须存在的。
配置文件的方式
1.注入的属性是引用类型的注入方式
Student类里面有一个School类型的属性
第一种方式:
<bean id="mySchool" class="com.service.School">
<property name="name" value="GDOU"/>
<property name="address" value="湛江"/>
</bean>
<bean id="myStudent" class="com.service.Student">
<property name="name" value="梁子祥" />
<property name="age" value="21" />
<property name="school" ref="mySchool"/>
</bean>
第二种方式:
使用自动注入,通过使用autowire=byName
byName的方式是:配置文件xml里面的bean对象的id要和类里面属性的名称相同,而且类型也需要相同,下面的示例里面bean的id是school,类型是School,和Student类里面的属性完全符合。
<!--通过自动注入的方式,注入引用类型的属性-->
<bean id="myStudent03" class="com.service.Student" autowire="byName">
<property name="name" value="梁子祥"/>
<property name="age" value="21"/>
</bean>
<bean id="school" class="com.service.School">
<property name="name" value="GDOU"/>
<property name="address" value="珠海"/>
</bean>
第三种方式:
也是自动注入,通过autowire=byType实现
byType的方法是去寻找和类中属性类型相同或者是继承,实现等关系的bean对象,将其赋值给属性,但这种赋值方式,如果有多个属性类型符合的bean则会出现错误,spring容器不知道要将那个bean对象赋值给类。
<!--通过自动注入的方式,注入引用类型的属性-->
<bean id="myStudent03" class="com.service.Student" autowire="byType">
<property name="name" value="梁子祥"/>
<property name="age" value="21"/>
</bean>
<!--自动注入,使用byType-->
<bean id="school" class="com.service.School">
<property name="name" value="GDOU"/>
<property name="address" value="珠海"/>
</bean>
2.无参构造的方法,通过set方法实现属性注入,示例查看初体验的代码
主要使用property标签
3.使用构造注入的方法
实现构造注入,需要再类中实现有参构造的方法,构造注入的方法底层原理是调用类的有参构造,主要使用constructor-arg标签
<bean id="myStudent02" class="com.service.Student">
<constructor-arg name="name" value="梁子祥"/>
<constructor-arg name="age" value="21"/>
<constructor-arg name="school" ref="mySchool"/>
</bean>
<bean id="mySchool" class="com.service.School">
<property name="name" value="GDOU"/>
<property name="address" value="湛江"/>
</bean>
除了可以使用name属性确定需要注入的属性,还可以使用index属性,index属性使用了参数的顺序,来确定属性的位置,也就是通过索引赋值。也可以省略name或者index,这默认了使用index且顺序是参数的顺序进行赋值。
基于注解的方式进行属性注入
注解的使用方式:
常见的注解:
@Component:用来创建对象
除了@Component,创建对象的注解还有:
@Repository:用在持久层上面,dao对象,可以访问数据库
@Service:用在业务层上面的,是做业务处理和事务功能的
@Controller:用在控制器上面的,可以创建控制器对象,可以接收用户提交的参数和显示请求的结果的
这三个注解可以给项目的对象进行分层
@Value可以给属性注入值,两种使用方法,一个在属性的定义上面,另外一个在set方法上面
@Autowired可以给引用类型赋值,使用的是自动注入的原理,默认使用byType方式,还可以使用byName方式,可以在属性上面或者set方法上面
@Qualifier和@Autowired搭配使用,即为byName 的方式
@Resource这是JDK提供的注解,也可以给引用类型进行自动赋值,同样支持byType和byName,默认byName,类似于@Autowired,先使用byName赋值,找不到与属性名相同的,再使用byType
注解使用初体验
创建一个对象School,添加@Component, @Value注解
package com;
import javafx.scene.chart.ValueAxis;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "mySchool")
public class School {
@Value("广东海洋大学")
private String name;
@Value("湛江")
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
2.在创建一个Student对象,添加@Component, @Value,@Autowired, @Qualifier注解
@Autowired里面有一个required属性,有true或false选项,当为true时,引用类型赋值失败时,会结束赋值;当为false,引用失败时,会使用null赋值。
默认为true,建议为true
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Component: 这个注解是用于创建对象的,value的值就是对象的名称,是唯一的
/*除了@Component,创建对象的注解还有:
*@Repository:用在持久层上面,dao对象,可以访问数据库
*@Service:用在业务层上面的,是做业务处理和事务功能的
*@Controller:用在控制器上面的,可以创建控制器对象,可以接收用户提交的参数和显示请求的结果的
* 这三个注解可以给项目的对象进行分层
* */
@Component(value = "myStudent")
public class Student {
@Value(value = "张三")
private String name;
@Value(value = "22")
private Integer age;
@Autowired
@Qualifier(value = "mySchool")
private School school;
public String getName() {
return name;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
3.配置组件扫描器,这个很重要!!
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--使用注解方式创建对象时,要申明组件扫描器-->
<context:component-scan base-package="com"/>
</beans>
4.进行测试,从spring容器中取出对象
package com;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest01 {
@Test
public void test01(){
String config = "applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
Student student = applicationContext.getBean("myStudent", Student.class);
System.out.println(student);
}
}
属性配置文件
1.创建一个属性配置文件test.properties
myname=zhangsan
myage=20
2.在spring配置文件里面添加识别属性配置文件的代码
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--使用注解方式创建对象时,要申明组件扫描器-->
<context:component-scan base-package="com"/>
<!--识别和加载属性配置文件 -->
<context:property-placeholder location="classpath:test.properties"/>
</beans>
3.使用注解的方式在创建对象
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
//@Component: 这个注解是用于创建对象的,value的值就是对象的名称,是唯一的
/*除了@Component,创建对象的注解还有:
*@Repository:用在持久层上面,dao对象,可以访问数据库
*@Service:用在业务层上面的,是做业务处理和事务功能的
*@Controller:用在控制器上面的,可以创建控制器对象,可以接收用户提交的参数和显示请求的结果的
* 这三个注解可以给项目的对象进行分层
* */
@Component(value = "myStudent")
public class Student {
@Value(value = "${myname}")
private String name;
@Value(value = "${myage}")
private Integer age;
@Resource
private School school;
public String getName() {
return name;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}