目录
第四步:在resource资源文件目录下创建application.xml文件
Spring核心功能IoC:
概述:
IOC(Inversion of Control):控制反转,是一种理论,概念,思想。把对象的创建,赋值,管理工作交给代码之外的容器实现,也就是对象的创建是由其他的外部资源完成。
什么是控制反转:
- 控制:创建对象,对象的属性赋值,对象之间的关系管理。
- 反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。由容器代替开发人员管理对象,创建对象。
- 正转:由开发人员在代码中实现,使用new构造方法创建对象,开发人员主动管理对象。
- 容器:一个服务器软件,一个框架(spring)
Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件,这些对象被称为 Spring Beans。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。
Java中创建对象的方式:
- 构造方法
- 反射
- 克隆
- 序列化
- ioc创建对象
- 动态代理
使用IoC的目的:减少对代码的改动,也能实现不同功能。实现解耦合。
IoC容器:
Spring 提供了以下两种不同类型的容器:
容器 & 描述 | |
---|---|
1 |
Spring BeanFactory 容器 它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。 |
2 |
Spring ApplicationContext 容器 该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。 |
ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常不建议使用BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
IOC的技术实现 :
DI 是ioc的技术实现。
DI(Dependency Injection):依赖注入, 只需要在程序中提供要使用的对象名称就可以, 至于对象如何在容器中创建,赋值,查找都由容器内部实现。
spring是使用的di实现了ioc的功能, spring底层创建对象,使用的是反射机制。
spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。
spring-conetxt 和 spring-webmvc 是spring中的两个模块
spring-context:是ioc功能的,创建对象的。
spring-webmvc做web开发使用的, 是servlet的升级。
spring-webmvc中也会用到spring-context中创建对象的功能的。
Spring的第一个程序:
第一步:创建一个Maven工程
导入Spring和junit依赖到pom.xml中:
<!--junit单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--Spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
第二步:创建一个接口
创建一个接口类,在通常业务中,我们通常使用接口来声明方法,通过接口实现类来完成方法,业务逻辑的具体实现!
package org.example;
public interface SomeService {
void doSome();
}
第三步:创建接口实现类
实现接口中声明的方法:
package org.example.imp;
import org.example.SomeService;
public class SomeServiceImpl implements SomeService {
//空参构造器:spring默认调用:
public SomeServiceImpl() {
System.out.println("spring调用了SomeServiceImpl的空参构造器!");
}
@Override
public void doSome() {
System.out.println("执行了SomeServiceImp的doSome方法!");
}
}
第四步:在resource资源文件目录下创建application.xml文件
把创建好的实现类交给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">
<!-- 约束文件路径——xml文件-->
<!--
告诉spring创建对象
声明bean,就是告诉spring要创建某个类的对象
id:对象的自定义名称,唯一值。spring通过这个名称找到对象
class:类的全限定名称(不能是接口,因为spring是反射机制创建对象,必须使用类)
-->
<bean id="someService" class="org.example.imp.SomeServiceImpl" />
<bean id="someService1" class="org.example.imp.SomeServiceImpl" />
<!-- spring底层完成:SomeService someService = new SomeServiceImp();
spring把创建好的对象放入map中,spring框架有一个map存放对象
springMap.put(id值,对象);
一个bean标签声明一个Java对象。
-->
<!--
spring能创建一个非自定义类的对象,创建一个存在的某个类的对象。
-->
<bean id="mydate" class="java.util.Date"/>
</beans>
<!--
spring的配置文件
1.beans:根标签,spring把Java对象称为bean
2.spring-beans.xsd 是约束文件,和mybatis指定 dtd 类似
-->
第五步:创建测试类
package org.example;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
public class MyTest {
/*
spring默认创建对象的时间:在创建spring的容器时,会创建配置文件中所有的对象。
spring创建对象:默认调用的是无参构造方法
*/
@Test
public void test01(){
//使用spring容器创建对象:
//1.指定spring配置文件名称
String config = "application.xml";
//2.创建表示spring容器的对象,ApplicationContext
//ApplicationContext就是表示spring容器,通过容器对象获取对象
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//从容其中获取某个对象,调用对象方法
//getBean("配置文件中bean的id值")
SomeService service = (SomeService) ac.getBean("someService");
//使用spring创建好的对象,调用方法:
service.doSome();
}
/**
* 获取spring容器中Java对象信息
*/
@Test
public void test02(){
String config = "application.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//使用spring提供的方法,获取容器中定义的对象数量
int num = ac.getBeanDefinitionCount();
System.out.println("容器中所含对象数量:" + num);
//容器中每个定义对象的名称
String[] names = ac.getBeanDefinitionNames();
//增强for循环:
for (String name : names){
System.out.println(name);
}
}
/**
* 获取一个非自定义类的对象
*/
@Test
public void test03(){
String config = "application.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//使用getBean();获取对象
Date md = (Date) ac.getBean("mydate");
System.out.println("系统时间:" + md);
}
}
基于XML文件的DI依赖注入:
Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系。在spring的XML配置文件中,给java对象的属性赋值。DI注入:创建对象,给属性赋值。
DI的语法分类:
依赖注入类型 & 描述 | |
---|---|
1 | Constructor-based dependency injection(构造器方法注入) 当容器调用带有多个参数的构造函数类时,实现基于构造函数的 DI,每个代表在其他类中的一个依赖关系。 |
2 | Setter-based dependency injection(setter方法注入) 基于 setter 方法的 DI 是通过在调用无参数的构造函数或无参数的静态工厂方法实例化 bean 之后容器调用 beans 的 setter 方法来实现的。 |
- set注入(设置注入):Spring调用类的set方法,在set方法中实现属性的赋值。
- 构造注入:Spring调用类的有参构造方法,创建对象,在构造方法中完成赋值。
setter设值注入:
当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了。
第一步:创建一个实体类
package org.example.ba01;
public class Student {
String name;
int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
第二步:第二步:在resource目录下编写application.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">
<!--声明student对象-->
<!--
注入:赋值
di:给属性赋值
简单类型:spring规定在Java的基本数据类型和String都是简单类型。
1.set注入(设置注入):spring调用类的set方法,你可以在set方法中完成属性赋值
1)简单类型注入
<bean id="XXX" class="YYY">
<property name="属性名字" value="此属性的值" />
一个property只能给一个属性赋值
<property ... >
</bean>
2) 引用类型的注入:spring调用类的set方法
<bean id="XXX" class="YYY">
<property name="属性名称" ref="bean的id(对象名称)"/>
</bean>
-->
<bean id="mystudent" class="org.example.ba01.Student">
<property name="name" value="TOM"/>
<property name="age" value="19"/>
</bean>
</beans>
第三步:编写测试类
package org.example;
import org.example.ba01.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01(){
//定义配置文件路径:
String config = "application.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//从容器中获得student
Student myStudent = (Student) ac.getBean("mystudent");
System.out.println("studnet对象:" + myStudent);
}
}
构造注入:
当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。
第一步:创建实体类
package org.example.ba01;
public class School {
String name;
int number;
public School(String name, int number) {
this.name = name;
this.number = number;
}
public School(){
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", number=" + number +
'}';
}
}
package org.example.ba01;
public class Student {
String name;
int age;
//声明一个引用类型
School school;
public Student(){
}
//创建有参构造方法:
public Student(String name, int age,School school) {
System.out.println("Student有参构造方法,给属性赋值!");
this.name = name;
this.age = age;
this.school = school;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
第二步:在resource目录下编写application.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">
<!--
2.构造注入:spring调用类的有参构造方法,在创建对象的同时,在构造方法中给属性赋值。
构造注入使用 <constructor-arg>标签
<constructor-arg>标签:一个<constructor-arg>表示构造方法一个参数。
<constructor-arg>标签属性:
name:表示构造方法名
index:表示构造方法的参数位置,参数从左往右位置是 0,1,2...的顺序
value:构造方法的形参类型是简单类型使用,value
ref:构造方法的形参类型是引用类型的,使用ref
-->
<!-- 声明School对象-->
<bean id="mySchool" class="org.example.ba01.School">
<constructor-arg name="name" value="大学"/>
<constructor-arg name="number" value="100"/>
</bean>
<!-- 声明Student对象-->
<bean id="myStudent" class="org.example.ba01.Student">
<!-- <constructor-arg name="name" value="Tom"/>-->
<!-- <constructor-arg name="age" value="19"/>-->
<!-- <constructor-arg name="school" ref="mySchool"/>-->
<!-- 使用:index属性,进行赋值:-->
<constructor-arg index="0" value="Hurry"/>
<constructor-arg index="1" value="19"/>
<constructor-arg index="2" ref="mySchool"/>
<!-- index属性可以省略,省略后注意赋值顺序和构造函数的排序一致!-->
</bean>
</beans>
第三步:编写测试类
package org.example;
import org.example.ba01.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
//1.创建配置文件路径:
String config = "application.xml";
//2.创建容器:
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//3.从容器中获取对象:
Student myStudent = (Student) ac.getBean("myStudent");
//4.通过对象调用方法:
System.out.println("Student : " + myStudent);
}
}
注入内部 Beans:
Java 内部类是在其他类的范围内被定义的,同理,inner beans 是在其他 bean 的范围内定义的 bean。因此<property />或<constructor-arg />元素中的<bean />元素称为内部bean。
<?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-3.0.xsd">
<bean id="outerBean" class="...">
<property name="target">
<bean id="innerBean" class="..."/>
</property>
</bean>
</beans>
内部 Bean 的定义不需要指定 id 和 name 。如果指定了,容器也不会将其作为区分 Bean 的标识符,反而会无视内部 Bean 的 scope 属性。所以内部 Bean 总是匿名的,而且总是随着外部 Bean 创建。
第一步:创建实体类
public class Person {
private Man man;
public Man getMan() {
return man;
}
public void setMan(Man man) {
System.out.println("在setMan方法内");
this.man = man;
}
public void man() {
man.show();
}
}
public class Man {
private String name;
private int age;
public Man() {
System.out.println("在man的构造函数内");
}
public Man(String name, int age) {
System.out.println("在man的有参构造函数内");
this.name = name;
this.age = age;
}
public void show() {
System.out.println("名称:" + name + "\n年龄:" + 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;
}
}
第二步:在resource目录下编写application.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-3.0.xsd">
<bean id="person" class="net.biancheng.Person">
<property name="man">
<bean class="net.biancheng.Man">
<property name="name" value="bianchengbang" />
<property name="age" value="12" />
</bean>
</property>
</bean>
</beans>
第三步:编写测试类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Person person = (Person) context.getBean("person");
person.man();
}
}
注入集合:
传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,应该怎么做呢。为了处理这种情况,Spring 提供了四种类型的集合的配置元素,如下所示:
标签 | 说明 |
---|---|
<list> | 用于注入 list 类型的值,允许重复 |
<set> | 用于注入 set 类型的值,不允许重复 |
<map> | 用于注入 key-value 的集合,其中 key-value 可以是任意类型 |
<props> | 用于注入 key-value 的集合,其中 key-value 都是字符串类型 |
可以使用<list>
或<set>
来连接任何 java.util.Collection
的实现或数组。
第一步:创建实体类
import java.util.*;
public class JavaCollection {
List addressList;
Set addressSet;
Map addressMap;
Properties addressProp;
// a setter method to set List
public void setAddressList(List addressList) {
this.addressList = addressList;
}
// prints and returns all the elements of the list.
public List getAddressList() {
System.out.println("List Elements :" + addressList);
return addressList;
}
// a setter method to set Set
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
// prints and returns all the elements of the Set.
public Set getAddressSet() {
System.out.println("Set Elements :" + addressSet);
return addressSet;
}
// a setter method to set Map
public void setAddressMap(Map addressMap) {
this.addressMap = addressMap;
}
// prints and returns all the elements of the Map.
public Map getAddressMap() {
System.out.println("Map Elements :" + addressMap);
return addressMap;
}
// a setter method to set Property
public void setAddressProp(Properties addressProp) {
this.addressProp = addressProp;
}
// prints and returns all the elements of the Property.
public Properties getAddressProp() {
System.out.println("Property Elements :" + addressProp);
return addressProp;
}
}
第二步:在resource目录下编写application.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-3.0.xsd">
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.tutorialspoint.JavaCollection">
<!-- results in a setAddressList(java.util.List) call -->
<property name="addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<!-- results in a setAddressSet(java.util.Set) call -->
<property name="addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
<!-- results in a setAddressMap(java.util.Map) call -->
<property name="addressMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="USA"/>
</map>
</property>
<!-- results in a setAddressProp(java.util.Properties) call -->
<property name="addressProp">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
</bean>
</beans>
第三步:创建测试类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("application.xml");
JavaCollection jc=(JavaCollection)context.getBean("javaCollection");
jc.getAddressList();
jc.getAddressSet();
jc.getAddressMap();
jc.getAddressProp();
}
}
注入Bean引用:
<?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-3.0.xsd">
<!-- Bean Definition to handle references and values -->
<bean id="..." class="...">
<!-- Passing bean reference for java.util.List -->
<property name="addressList">
<list>
<ref bean="address1"/>
<ref bean="address2"/>
<value>Pakistan</value>
</list>
</property>
<!-- Passing bean reference for java.util.Set -->
<property name="addressSet">
<set>
<ref bean="address1"/>
<ref bean="address2"/>
<value>Pakistan</value>
</set>
</property>
<!-- Passing bean reference for java.util.Map -->
<property name="addressMap">
<map>
<entry key="one" value="INDIA"/>
<entry key ="two" value-ref="address1"/>
<entry key ="three" value-ref="address2"/>
</map>
</property>
</bean>
</beans>
注入 null 和空字符串的值:
<bean id="..." class="exampleBean">
<property name="email" value=""/>
</bean>
<bean id="..." class="exampleBean">
<property name="email"><null/></property>
</bean>
自动注入:
自动装配就是指 Spring 容器在不使用 <constructor-arg> 和<property> 标签的情况下,可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。
自动装配模式:
下列自动装配模式,它们可用于指示 Spring 容器为来使用自动装配进行依赖注入。你可以使用<bean>
元素的 autowire 属性为一个 bean 定义指定自动装配模式。
名称 | 说明 |
---|---|
no | 默认值,表示不使用自动装配,Bean 依赖必须通过 ref 元素定义。 |
byName | 根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的 Property 的 name 相同,则自动装配这个 Bean 到 Property 中。 |
byType | 根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配。 |
constructor | 类似于 byType,根据构造方法参数的数据类型,进行 byType 模式的自动装配。 |
autodetect(3.0版本不支持) | 如果 Bean 中有默认的构造方法,则用 constructor 模式,否则用 byType 模式。 |
可以使用 byType 或者 constructor 自动装配模式来连接数组和其他类型的集合。
自动装配的局限性:
当自动装配始终在同一个项目中使用时,它的效果最好。如果通常不使用自动装配,它可能会使开发人员混淆的使用它来连接只有一个或两个 bean 定义。不过,自动装配可以显著减少需要指定的属性或构造器参数,但你应该在使用它们之前考虑到自动装配的局限性和缺点。
限制 | 描述 |
---|---|
重写的可能性 | 你可以使用总是重写自动装配的 <constructor-arg>和 <property> 设置来指定依赖关系。 |
原始数据类型 | 你不能自动装配所谓的简单类型包括基本类型,字符串和类。 |
混乱的本质 | 自动装配不如显式装配精确,所以如果可能的话尽可能使用显式装配。 |
ByName:
第一步:创建实体类
package org.example.ba02;
public class School {
String name;
int number;
public School(String name, int number) {
this.name = name;
this.number = number;
}
public School(){
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", number=" + number +
'}';
}
}
package org.example.ba02;
public class Student {
String name;
int age;
//声明一个引用类型
School school = null;//要和配置文件中School类的<bean>的id值相同
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSchool(School school) {
this.school = school;
}
}
第二步:在resource目录下编写application.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">
<!--
引用类型的自动注入:spring框架根据某些规则可以给引用类型给类型赋值,不用你在给引用类型赋值
使用的规则常用的是byName,byType.
1.byName(按名称注入):java类中引用类型的属性名和spring容器中(配置文件)<bean>id名称一样,且数据类型一致
这样的容器中的bean,spring就能够赋值给引用类型。
语法:
<bean id="XXX" class="YYY" autowire="byName">
简单类型属性赋值
</bean>
2.byType(按类型注入):java类中引用数据类型和spring容器中(配置文件)<bean>的class属性是同源关系,
这样的bean能够赋值给引用类型。
同源:同一类
1.Java类中引用类型的数据类型和bean的class的值是一样的。
2.Java类中引用类型的数据类型和bean的class的值是父子类关系的。
3.Java类中引用类型的数据类型和bean的class的值接口和实现类关系的。
语法:
<bean id="XXX" class="YYY" autowire="byType">
简单类型属性赋值
</bean>
-->
<!-- 声明School对象-->
<bean id="school" class="org.example.ba02.School"> <!--id值要和Student类的School属性名一致-->
<constructor-arg name="name" value="大学"/>
<constructor-arg name="number" value="100"/>
</bean>
<!-- 声明Student对象 byName自动注入-->
<bean id="myStudent" class="org.example.ba02.Student" autowire="byName">
<property name="name" value="AJX"/>
<property name="age" value="19"/>
</bean>
<!-- 声明Student对象 byType自动注入-->
<bean id="myStudent01" class="org.example.ba02.Student" autowire="byType">
<property name="name" value="Kay" />
<property name="age" value="20"/>
</bean>
</beans>
第三步:创建测试类
package org.example;
import org.example.ba02.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest01 {
@Test
public void test01(){
//1.创建配置文件路径:
String config = "application.xml";
//2.创建容器对象:
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//3.通过容器获取对象:
Student myStudent = (Student) ac.getBean("myStudent");
//4.通过对象调用方法:
System.out.println("Student :" + myStudent);
}
@Test
public void test02(){
//1.创建配置文件路径:
String config = "application.xml";
//2.创建容器对象:
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//3.通过容器获取对象:
Student myStudent = (Student) ac.getBean("myStudent01");
//4.通过对象调用方法:
System.out.println("Student :" + myStudent);
}
}
ByType:
这种模式由属性类型指定自动装配。Spring
容器看作 beans
,在 XML
配置文件中 beans
的 autowire
属性设置为 byType
。然后,如果它的 type
恰好与配置文件中 beans
名称中的一个相匹配,它将尝试匹配和连接它的属性。如果找到匹配项,它将注入这些 beans
,否则,它将抛出异常。
第一步:创建实体类
public class TextEditor {
private SpellChecker spellChecker;
private String name;
public void setSpellChecker( SpellChecker spellChecker ) {
this.spellChecker = spellChecker;
}
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
第二步:在resource目录下编写application.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-3.0.xsd">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor"
autowire="byType">
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="SpellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>
第三步:创建测试类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("application.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
由构造函数自动装配
这种模式与 byType 非常相似,但它应用于构造器参数。Spring 容器看作 beans,在 XML 配置文件中 beans 的 autowire 属性设置为 constructor。然后,它尝试把它的构造函数的参数与配置文件中 beans 名称中的一个进行匹配和连线。如果找到匹配项,它会注入这些 bean,否则,它会抛出异常。
基于注解的配置:
通过spring的注解完成Java对象的创建,属性的赋值。代替xml文件
从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。
在 XML 注入之前进行注解注入,因此后者的配置将通过两种方式的属性连线被前者重写。
注解连线在默认情况下在 Spring 容器中不打开。因此,在可以使用基于注解的连线之前,我们将需要在我们的 Spring 配置文件中启用它。所以如果你想在 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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config base-package="包路径"/>
<!-- bean definitions go here -->
</beans>
1)@Component
可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
2)@Repository
用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
3)@Service
通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
4)@Controller
通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
5)@Autowired
可以应用到 Bean 的属性变量、属性的 setter 方法、非 setter 方法及构造函数等,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。
6)@Resource
作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。
@Resource 中有两个重要属性:name 和 type。
Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
7)@Qualifier
与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
对象创建及基本属性注入:
第一步:创建实体类
package org.example;
import org.springframework.stereotype.Component;
/**
* @Component: 创建对象的,等同于<bean>的功能
* 属性:value 就是对象的名称,也就是bean的id值
* value的值是唯一的,创建的对象在整个spring容器中就一个
* 位置:在类的上面
*
* @Component(value = "myStudent")等同于 <bean id="myStudent" class="org.example.Student" />
*
* spring中和@component 功能一致,创建对对象的注解还有:
* 1、@Repository(用在持久层类的上面):放在dao的实现类的上面,表示创建dao对象,dao对象是能访问数据库的。
* 2、@Service(用在业务层类的上面):放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事务功能的。
* 3、@Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的
*
* 以上三个注解使用语法和@Component一致。都能创建对象,但是这三个注释还有额外的功能
*
* @Repository,@Service,@Controller是给项目对象分层的。
*/
//省略value
//@Component("myStudent")
//不指定对象名称,由spring默认提供,value值为:类名首字母小写
//@Component
//显示的使用value属性
@Component(value = "myStudent")
public class Student {
String name;
int age;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
第二步:在resource目录下编写application.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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--
声明组件扫描器(component-scan)
组件:Java对象
base-package:指定注解在你的项目中的包名
component-scan工作方式:spring会扫描遍历base-package指定的包,把包中的所有类,
找到类中的注解,按照注解功能创建对象,给属性赋值
加入component-scan标签,配置文件的变化:
http://www.springframework.org/schema/context ——命名空间
https://www.springframework.org/schema/context/spring-context.xsd ——url
1.加入一个新的约束文件spring-context.xsd
2.给这个新的约束文件起个命名空间的名称
-->
<context:component-scan base-package="org.example"/>
</beans>
第三步:创建测试类
package org.example;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01(){
//1.创建配置文件路径:
String config = "applicationContext.xml";
//2.创建容器:
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//3.通过容器获取对象:
Student myStudent = (Student) ac.getBean("myStudent");
//4.通过对象调用方法:
System.out.println("Student:" + myStudent);
}
}
扫描多个包:
<!--指定多个包扫描的三种方式--> <!--第一种方式:使用多次扫描组件,指定不同的包--> <context:component-scan base-package="包路径1"/> <context:component-scan base-package="包路径2"/> <!--第二种方式:使用分隔符(;或者,)分隔多个包--> <context:component-scan base-package="包路径1;包路径2"/> <!--第三种方式:指定父包--> <context:component-sacn base-package="父包"/>
引用类型注入:
第一步:创建实体类
package org.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("mySchool")
public class School {
@Value("重庆邮电大学")
String name;
@Value("南山之颠,黄河以北")
String address;
public School() {
}
public School(String name, String address) {
this.name = name;
this.address = address;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
package org.example;
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;
@Component(value = "myStudent")
public class Student {
/**
* @Value: 简单类型的属性赋值
* 属性:value 是String类型的,表示简单类型的属性值
* 位置:1.在属性定义的上面,无需set方法 (推荐使用)
* 2.在set方法的上面
*
*
* @Valude: 引用类型的属性赋值
* @Autowired: spring框架提供注解,实现引用类型的赋值。
* spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
*
* @Autowired:默认使用byType自动注入
*
* 属性:
* required ,是一个boolean类型的,默认true
* required=true:表示引用类型赋值失败,程序报错,并终止执行。
* required=false:表示引用类型赋值失败,程序正常执行,引用类型是null
*
* 位置:1.在属性定义的上面,无需set方法(推荐使用)
* 2.在set方法上面
*
* @Autowired:使用byName注入方式:
* 1.在属性上加@Autowired
* 2.在属性上加入@Quallifier(value="bean的id") :表示使用指定名称的bean完成对象创建
*
*
* 引用类型
* @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用他给引用类型属性赋值。
* 使用的也是自动类型注入原理,支持byName,byType,默认是byName
*
* 位置:1.在属性上方定义,无需set方法(推荐使用)
* 2.在set方法上
*
* @Resource:只是用byName方式,需要增加一个属性 name
* name的值是bean的id(名称)
*/
//默认是byName:先使用byName自定注入,如果byName赋值失效,再使用byType
// @Value(value = "Tom") //value可以省
// 使用资源文件赋值:
@Value("${name}")
String name;
// @Value(value = "21")
@Value("${age}")
int age;
//引用类型属性:
@Autowired
@Qualifier(value = "mySchool")
School school;
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// @Value(value = "harry")
// public void setName(String name) {
// this.name = name;
// }
//
// public void setAge(int age) {
// this.age = age;
// }
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
第二步: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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--
声明组件扫描器(component-scan)
组件:Java对象
base-package:指定注解在你的项目中的包名
component-scan工作方式:spring会扫描遍历base-package指定的包,把包中的所有类,
找到类中的注解,按照注解功能创建对象,给属性赋值
加入component-scan标签,配置文件的变化:
http://www.springframework.org/schema/context ——命名空间
https://www.springframework.org/schema/context/spring-context.xsd ——url
1.加入一个新的约束文件spring-context.xsd
2.给这个新的约束文件起个命名空间的名称
-->
<context:component-scan base-package="org.example"/>
<!-- 声明资源文件路径-->
<context:property-placeholder location="MyResource.properties"/>
</beans>
properties配置文件
name=Tom
age=190
第三步:编写测试类
package org.example;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01(){
//1.创建配置文件路径:
String config = "applicationContext.xml";
//2.创建容器:
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//3.通过容器获取对象:
Student myStudent = (Student) ac.getBean("myStudent");
//4.通过对象调用方法:
System.out.println("Student:" + myStudent);
}
}