参考:https://gitee.com/turnon/spring-tutorial
参考:https://www.bilibili.com/video/BV1kR4y1b7Qc?p=1&vd_source=0c3c1f43c75954a15fba4e42c1d7883e
Spring 当前框架有20个 jar 包,大致可以分为6大模块
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-turbo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>spring-turbo-01-hello</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.15</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
package com.example.bean;
public class Hello {
public void sayHello(){
System.out.println("hello 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="hello" class="com.example.bean.Hello"></bean>
</beans>
import com.example.bean.Hello;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloTest {
@Test
public void testHello(){
ApplicationContext app = new ClassPathXmlApplicationContext("1-1-hello.xml");
Hello h = (Hello) app.getBean("hello");
h.sayHello();
}
}
<bean id="hello" class="com.example.bean.HelloWorld"></bean>
Class clazz = Class.forName("com.example.bean.HelloWorld");
// Object obj = clazz.newInstance();
Object object = clazz.getDeclaredConstructor().newInstance();
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
beanDefinitionMap.put("hello",object)
public Object getBean(String name){
Object obj =beanDefinitionMap.get(name);
return obj;
}
类型名 | 简介 |
---|---|
ClassPathXmlApplicationContext | 通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象 |
FileSystemXmlApplicationContext | 通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象 |
ConfigurableApplicationContext | ApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的能力。 |
WebApplicationContext | 专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。 |
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.26</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
package com.example.bean;
public interface PersonInterface {
void sayHello();
}
package com.example.bean.impl;
public class Person {
public void sayHello(){
System.out.println("hello, i'm person~");
}
}
package com.example.bean.impl;
import com.example.bean.PersonInterface;
public class Student extends Person implements PersonInterface {
@Override
public void sayHello() {
System.out.println("hello, i'm student~");
}
}
package com.example.bean.impl;
import com.example.bean.PersonInterface;
public class Teacher extends Person implements PersonInterface {
@Override
public void sayHello() {
System.out.println("hello, i'm teacher~");
}
}
<?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="student1" class="com.example.bean.impl.Student" name="myStudent"></bean>
<bean id="student2" class="com.example.bean.impl.Student"></bean>
<!-- name 和id类似,一般不用 -->
</beans>
import com.example.bean.PersonInterface;
import com.example.bean.impl.Person;
import com.example.bean.impl.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
/**
* 获取bean
*/
public class GetBeanTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
// 方式一:根据id获取
// 由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象
Student s1 = (Student) app.getBean("student1");
s1.sayHello();
// 方式二:根据类型获取
// 当根据类型获取bean时,要求IOC容器中指定类型的bean有且只能有一个
// IOC容器中配置了多个同类型的bean时, 根据类型获取时会抛出异常
// Student s2 = app.getBean(Student.class);
// s2.sayHello();
// 方式三:根据id和类型
Student s3 = app.getBean("student1", Student.class);
s3.sayHello();
// 如果组件类实现了接口,可以根据接口类型获取bean, 前提是bean唯一
// 同理:如果组件类继承了父类,可以根据父类类型获取bean, 前提是bean唯一
// 如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类不可以可以获取bean, 因为bean不唯一
// PersonInterface p1 = app.getBean(PersonInterface.class);
// Person p2 = app.getBean(Person.class);
// p1.sayHello();
// p2.sayHello();
// 结论
// 根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类型』的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。
// java中,instanceof运算符用于判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。
// 也就是说:用instanceof关键字做判断时, instanceof 操作符的左右操作必须有继承或实现关系
String[] personInterfaces = app.getBeanNamesForType(PersonInterface.class);
System.out.println(Arrays.toString(personInterfaces)); // [student1, student2]
}
}
package com.example.bean;
public class Student {
private String name;
private int sid;
private int grade;
public void setName(String name) {
this.name = name;
}
public void setSid(int sid) {
this.sid = sid;
}
public void setGrade(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sid=" + sid +
", grade=" + grade +
'}';
}
}
<?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">
<!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
<!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
<!-- value属性:指定属性值 -->
<bean id="student" class="com.example.bean.Student">
<property name="name" value="张三"></property>
<property name="sid" value="10001"></property>
<property name="grade" value="1"></property>
</bean>
</beans>
import com.example.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 依赖注入之setter注入
*/
public class SetBeanTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
Student s = (Student) app.getBean("student");
System.out.println(s);
}
}
package com.example.bean;
public class Student {
private String name;
private int sid;
private int grade;
public Student(){
}
public Student(String name, int sid, int grade){
this.name = name;
this.sid = sid;
this.grade = grade;
System.out.println("有参构造函数执行了, name="+name+", sid=" + sid + ", grade="+grade);
}
public void setName(String name) {
this.name = name;
}
public void setSid(int sid) {
this.sid = sid;
}
public void setGrade(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sid=" + sid +
", grade=" + grade +
'}';
}
}
<?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">
<!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
<!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
<!-- value属性:指定属性值 -->
<bean id="student" class="com.example.bean.Student">
<property name="name" value="张三"></property>
<property name="sid" value="10001"></property>
<property name="grade" value="1"></property>
</bean>
<!-- constructor-arg标签还有两个属性可以进一步描述构造器参数 -->
<!-- index属性:指定参数所在位置的索引(从0开始)-->
<!-- name属性:指定参数名 -->
<bean id="student2" class="com.example.bean.Student">
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="sid" value="10002"></constructor-arg>
<constructor-arg name="grade" value="1"></constructor-arg>
</bean>
</beans>
import com.example.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 依赖注入之setter注入
* 依赖注入之构造器注入
*/
public class SetBeanTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
// 调用无参构造
Student s = (Student) app.getBean("student");
System.out.println(s);
// 调用有参构造
Student s2 = (Student) app.getBean("student2");
System.out.println(s2);
}
}
<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>
<property name="grade">
<null />
</property>
大于号、小于号在XML文档中用来定义标签的开始,不能随便使用
< | < | 小于号 |
---|---|---|
> | > | 大于号 |
& | & | 和 |
' | ’ | 单引号 |
" | " | 双引号 |
package com.example.bean;
public class Student {
private String name;
private Integer sid;
private Integer grade;
public Student(){
}
public Student(String name, Integer sid, Integer grade){
this.name = name;
this.sid = sid;
this.grade = grade;
System.out.println("有参构造函数执行了, name="+name+", sid=" + sid + ", grade="+grade);
}
public void setName(String name) {
this.name = name;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sid=" + sid +
", grade=" + grade +
'}';
}
}
<?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">
<!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
<!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
<!-- value属性:指定属性值 -->
<bean id="student" class="com.example.bean.Student">
<property name="name" value="张三"></property>
<property name="sid" value="10001"></property>
<property name="grade" value="1"></property>
</bean>
<!-- constructor-arg标签还有两个属性可以进一步描述构造器参数 -->
<!-- index属性:指定参数所在位置的索引(从0开始)-->
<!-- name属性:指定参数名 -->
<bean id="student2" class="com.example.bean.Student">
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="sid" value="10002"></constructor-arg>
<constructor-arg name="grade" value="2"></constructor-arg>
</bean>
<!-- 属性值设置为null -->
<bean id="student3" class="com.example.bean.Student">
<property name="name" value="王五"></property>
<property name="sid" value="10003"></property>
<property name="grade">
<null/>
</property>
</bean>
<!-- 属性值设置为特殊字符 xml实体 -->
<bean id="student4" class="com.example.bean.Student">
<property name="name" value=""<'赵&六'>""></property>
<property name="sid" value="10004"></property>
<property name="grade" value="4"></property>
</bean>
<!-- 属性值设置为特殊字符 CDATA -->
<bean id="student5" class="com.example.bean.Student">
<property name="name">
<value><![CDATA['<爱丽丝>']]></value>
</property>
<property name="sid" value="10005"></property>
<property name="grade" value="5"></property>
</bean>
</beans>
import com.example.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 依赖注入之setter注入
* 依赖注入之构造器注入
* 特殊值处理
*/
public class SetBeanTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
// 调用无参构造
Student s = (Student) app.getBean("student");
System.out.println(s);
// 调用有参构造
Student s2 = (Student) app.getBean("student2");
System.out.println(s2);
// 属性设置为null
Student s3 = (Student) app.getBean("student3");
System.out.println(s3);
// 属性设置为特殊字符-xml
Student s4 = (Student) app.getBean("student4");
System.out.println(s4);
// 属性设置为特殊字符-CDATA
Student s5 = (Student) app.getBean("student5");
System.out.println(s5);
}
}
package com.example.bean;
public class Student {
private String name;
private Integer sid;
private Integer grade;
private Clazz clazz;
public Student(){
}
public Student(String name, Integer sid, Integer grade){
this.name = name;
this.sid = sid;
this.grade = grade;
System.out.println("有参构造函数执行了, name="+name+", sid=" + sid + ", grade="+grade);
}
public void setName(String name) {
this.name = name;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
public String getName() {
return name;
}
public Integer getSid() {
return sid;
}
public Integer getGrade() {
return grade;
}
public Clazz getClazz() {
return clazz;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sid=" + sid +
", grade=" + grade +
", clazz=" + clazz +
'}';
}
}
package com.example.bean;
public class Clazz {
private Integer clazzId;
private String clazzName;
public Integer getClazzId() {
return clazzId;
}
public void setClazzId(Integer clazzId) {
this.clazzId = clazzId;
}
public String getClazzName() {
return clazzName;
}
public void setClazzName(String clazzName) {
this.clazzName = clazzName;
}
@Override
public String toString() {
return "Clazz{" +
"clazzId=" + clazzId +
", clazzName='" + clazzName + '\'' +
'}';
}
public Clazz() {
}
public Clazz(Integer clazzId, String clazzName) {
this.clazzId = clazzId;
this.clazzName = clazzName;
}
}
<?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 -->
<bean id="clazz" class="com.example.bean.Clazz">
<property name="clazzId" value="1111"></property>
<property name="clazzName" value="财源滚滚班"></property>
</bean>
<bean id="student" class="com.example.bean.Student">
<property name="name" value="张三"></property>
<property name="sid" value="10001"></property>
<property name="grade" value="1"></property>
<!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
<property name="clazz" ref="clazz"></property>
</bean>
<!--
如果错把ref属性写成了value属性,会抛出异常
Caused by: java.lang.IllegalStateException: Cannot convert value of type
'java.lang.String' to required type 'com.example.bean.Clazz' for property 'clazz': no matching editors or conversion strategy found
意思是不能把String类型转换成我们要的Clazz类型,说明我们使用value属性时,Spring只把这个属性看做一个普通的字符串,不会认为这是一个bean的id,更不会根据它去找到bean来赋值
-->
<!-- 方式二:内部bean -->
<bean id="student2" class="com.example.bean.Student">
<property name="sid" value="10002"></property>
<property name="name" value="李四"></property>
<property name="grade" value="2"></property>
<property name="clazz">
<!-- 在一个bean中再声明一个bean就是内部bean -->
<!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
<bean id="clazzInner" class="com.example.bean.Clazz">
<property name="clazzId" value="2222"></property>
<property name="clazzName" value="远大前程班"></property>
</bean>
</property>
</bean>
<!-- 方式三:级联属性赋值 -->
<bean id="student3" class="com.example.bean.Student">
<property name="sid" value="10003"></property>
<property name="name" value="王五"></property>
<property name="grade" value="3"></property>
<property name="clazz" ref="clazz"></property>
<!-- 级联属性赋值 有一个注意点,该方式必须有get方法,否则会报属性找不到 -->
<property name="clazz.clazzId" value="3333"></property>
<property name="clazz.clazzName" value="最强王者班"></property>
</bean>
</beans
import com.example.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 为对象类型属性赋值
*/
public class SetBeanObjectTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
Student s = (Student) app.getBean("student");
System.out.println(s);
Student s2 = app.getBean("student2",Student.class);
System.out.println(s2);
Student s3 = app.getBean("student3",Student.class); // 同一个对象 s.clazz对象的属性值被修改
System.out.println(s3);
}
}
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
package com.example.bean;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Properties;
public class Student {
private String name;
private Integer sid;
private Integer grade;
private Clazz clazz;
private String[] hobbies;
private List<Clazz> hobbies2;
private Set<String> hobbies3;
private Map<String, Clazz> clazzMap;
private Properties properties;
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public List<Clazz> getHobbies2() {
return hobbies2;
}
public void setHobbies2(List<Clazz> hobbies2) {
this.hobbies2 = hobbies2;
}
public Set<String> getHobbies3() {
return hobbies3;
}
public void setHobbies3(Set<String> hobbies3) {
this.hobbies3 = hobbies3;
}
public Map<String, Clazz> getClazzMap() {
return clazzMap;
}
public void setClazzMap(Map<String, Clazz> clazzMap) {
this.clazzMap = clazzMap;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Student(){
}
public Student(String name, Integer sid, Integer grade){
this.name = name;
this.sid = sid;
this.grade = grade;
System.out.println("有参构造函数执行了, name="+name+", sid=" + sid + ", grade="+grade);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
public Clazz getClazz() {
return clazz;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sid=" + sid +
", grade=" + grade +
", clazz=" + clazz +
", hobbies=" + Arrays.toString(hobbies) +
", hobbies2=" + hobbies2 +
", hobbies3=" + hobbies3 +
", clazzMap=" + clazzMap +
", properties=" + properties +
'}';
}
}
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 为数组 List Set Properties类型属性赋值 -->
<bean id="student1" class="com.example.bean.Student">
<property name="name" value="张三"></property>
<property name="hobbies">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>
</array>
</property>
<property name="hobbies2">
<list>
<ref bean="clazz1"></ref>
<ref bean="clazz2"></ref>
</list>
</property>
<property name="hobbies3">
<set>
<value>抽烟3</value>
<value>喝酒3</value>
<value>烫头3</value>
</set>
</property>
<property name="properties">
<props>
<prop key="1">ABC</prop>
<prop key="2">DEF</prop>
</props>
</property>
</bean>
<!-- --------------------------------------------------------------------------- -->
<!-- 为Map集合类型属性赋值 -->
<bean id="clazz1" class="com.example.bean.Clazz">
<property name="clazzId" value="10001"></property>
<property name="clazzName" value="java"></property>
</bean>
<bean id="clazz2" class="com.example.bean.Clazz">
<property name="clazzId" value="10002"></property>
<property name="clazzName" value="python"></property>
</bean>
<bean id="student2" class="com.example.bean.Student">
<property name="name" value="李四"></property>
<property name="clazzMap">
<map>
<entry>
<key><value>c1</value></key>
<ref bean="clazz1"></ref>
</entry>
<entry>
<key><value>c2</value></key>
<ref bean="clazz2"></ref>
</entry>
</map>
</property>
</bean>
<!-- --------------------------------------------------------------------------- -->
<!-- util -->
<util:list id="clazzs">
<ref bean="clazz1"></ref>
<ref bean="clazz2"></ref>
</util:list>
<util:map id="clazzMap">
<entry>
<key><value>10010</value></key>
<ref bean="clazz1"></ref>
</entry>
<entry>
<key><value>10086</value></key>
<ref bean="clazz2"></ref>
</entry>
</util:map>
<bean id="student3" class="com.example.bean.Student">
<property name="name" value="王五"></property>
<property name="hobbies2" ref="clazzs"></property>
<property name="clazzMap" ref="clazzMap"></property>
</bean>
</beans>
import com.example.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 为对象类型属性赋值
*/
public class SetBeanUtilTest {
@Test
public void testGetBean(){
ApplicationContext app = new ClassPathXmlApplicationContext("utilBean.xml");
// 集合 list set
Student s = (Student) app.getBean("student1");
System.out.println(s);
// map
Student s2 = app.getBean("student2",Student.class);
System.out.println(s2);
// util
Student s3 = app.getBean("student3",Student.class);
System.out.println(s3);
}
}
package com.example.bean;
public class Person {
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 "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.example.bean.Person" p:name="张三" p:age="18"></bean>
</beans>
import com.example.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PBeanTest {
@Test
public void test(){
ApplicationContext app = new ClassPathXmlApplicationContext("pBean.xml");
Person person = app.getBean(Person.class);
System.out.println(person); // Person{name='张三', age=18}
}
}
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
<!-- 引入c命名空间 -->
xmlns:c="http://www.springframework.org/schema/c"
<!--c名称空间,就是对constructor-arg的简化-->
<bean id="person2" class="com.example.bean.Person" c:name="李四" c:age="20" ></bean>
import com.example.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PBeanTest {
@Test
public void test(){
ApplicationContext app = new ClassPathXmlApplicationContext("pBean.xml");
Person person = app.getBean("person", Person.class);
System.out.println(person);
Person person2 = app.getBean("person2", Person.class);
System.out.println(person2);
}
}
context:property-placeholder
xml文件中配置
<context:property-placeholder location="jdbc.properties,jdbc.properties"/>
<context:property-placeholder location="*.properties"/>
<context:property-placeholder location="classpath:*.properties" />
<context:property-placeholder location="classpath*:*.properties" />
不加载系统属性:system-properties-mode="NEVER"
<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="NEVER"/>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc.driver=com.mysql.cj.jdbc.Driver
<!-- 引入context 名称空间 -->
<?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:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 配置bean -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
</bean>
</beans>
注意:在使用context:property-placeholder元素加载外包配置文件功能前,首先需要在 XML 配置的一级标签 中添加 context 相关的约束。
import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.ResourceBundle;
public class JdbcTest {
@Test
public void test() throws SQLException, PropertyVetoException {
// TODO 系统属性
System.out.println("系统属性");
Map<String, String> env = System.getenv();
System.out.println(env);
System.out.println("----------------------");
// TODO 读取配置文件
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String userName = rb.getString("jdbc.user");
String password = rb.getString("jdbc.password");
// 创建数据源对象 设置连接参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(userName);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
System.out.println("-------------------------------");
// TODO xml文件
ApplicationContext app = new ClassPathXmlApplicationContext("jdbcBean.xml");
// DruidDataSource
DruidDataSource druidDataSource = app.getBean(DruidDataSource.class);
Connection connection2 = dataSource.getConnection();
System.out.println(connection2);
connection2.close();
System.out.println("-----------------------------------");
// c3p0
ComboPooledDataSource comboPooledDataSource = app.getBean(ComboPooledDataSource.class);
Connection connection3 = comboPooledDataSource.getConnection();
System.out.println(connection3);
connection3.close();
// TODO 手动创建c3p0数据源
ComboPooledDataSource comboPooledDataSource1 = new ComboPooledDataSource();
comboPooledDataSource1.setDriverClass("com.mysql.jdbc.Driver");
comboPooledDataSource1.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
comboPooledDataSource1.setUser("root");
comboPooledDataSource1.setPassword("123456");
Connection connection4 = comboPooledDataSource1.getConnection();
System.out.println(connection4);
connection4.close();
System.out.println("-----------------------------------");
// TODO 手动创建druid数据源
DruidDataSource druidDataSource1 = new DruidDataSource();
druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource1.setUrl("jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
druidDataSource1.setUsername("root");
druidDataSource1.setPassword("123456");
Connection connection5 = druidDataSource1.getConnection();
System.out.println(connection5);
connection5.close();
}
}
取值 | 含义 | 创建对象的时机 |
---|---|---|
singleton(默认) | 在IOC容器中,这个bean的对象始终为单实例 | IOC容器初始化时 |
prototype | 这个bean在IOC容器中有多个实例 | 获取bean时 |
取值 | 含义 |
---|---|
request | 在一个请求范围内有效 |
session | 在一个会话范围内有效 |
package com.example.bean;
public class Student {
private String name;
public Student() {
System.out.println("Student无参构造被执行了....");
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package com.example.bean;
public class Teacher {
private String name;
public Teacher() {
System.out.println("Teacher无参构造被执行了....");
}
public Teacher(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
<?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="teacher" class="com.example.bean.Teacher" scope="singleton"></bean>
<bean id="student" class="com.example.bean.Student" scope="prototype"></bean>
</beans>
import com.example.bean.Student;
import com.example.bean.Teacher;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ScopeTest {
@Test
public void test(){
ApplicationContext app = new ClassPathXmlApplicationContext("scopeBean.xml");
System.out.println("------------------");
Teacher teacher = app.getBean("teacher", Teacher.class);
System.out.println(teacher);
System.out.println("------------------");
Student student = app.getBean("student", Student.class);
System.out.println(student);
}
}
Teacher无参构造被执行了.... // 单例模式,bean在IOC容器中只有一个实例,IOC容器初始化时创建对象
------------------
Teacher{name='null'}
------------------
Student无参构造被执行了.... // bean在IOC容器中可以有多个实例,getBean()时创建对象
Student{name='null'}
bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行
package com.example.bean;
public class Person {
private Integer id;
private String username;
public Person() {
System.out.println("生命周期Person:1、创建对象");
}
public Person(Integer id, String username) {
this.id = id;
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("生命周期Person:2、依赖注入");
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void initMethod(){
System.out.println("生命周期Person:4、初始化");
}
public void destroyMethod(){
System.out.println("生命周期Person:7、销毁");
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", username='" + username +
'}';
}
}
package com.example.bean;
public class User {
private Integer id;
private String username;
public User() {
System.out.println("生命周期:1、创建对象");
}
public User(Integer id, String username) {
this.id = id;
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("生命周期:2、依赖注入");
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void initMethod(){
System.out.println("生命周期:4、初始化");
}
public void destroyMethod(){
System.out.println("生命周期:7、销毁");
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username +
'}';
}
}
package com.example.process;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("生命周期:3、bean的后置处理器(初始化之前)" + beanName + " = " + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("生命周期:5、bean的后置处理器(初始化之后)" + beanName + " = " + bean);
return 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.xsd">
<!-- 使用init-method属性指定初始化方法 -->
<!-- 使用destroy-method属性指定销毁方法 -->
<bean class="com.example.bean.User" scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1001"></property>
<property name="username" value="admin"></property>
</bean>
<bean class="com.example.bean.Person" scope="prototype" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="10011"></property>
<property name="username" value="张三"></property>
</bean>
<!-- bean的后置处理器要放入IOC容器才能生效 -->
<bean id="myBeanProcessor" class="com.example.process.MyBeanProcessor"/>
</beans>
import com.example.bean.Person;
import com.example.bean.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeTest {
@Test
public void testLife(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
System.out.println("---------------------");
User bean = ac.getBean(User.class);
System.out.println("生命周期:6、通过IOC容器获取bean并使用");
System.out.println("---------------------");
Person person = ac.getBean(Person.class);
System.out.println("生命周期Person:6、通过IOC容器获取bean并使用");
System.out.println("---------------------");
ac.close();
}
}
生命周期:1、创建对象
生命周期:2、依赖注入
生命周期:3、bean的后置处理器(初始化之前)com.example.bean.User#0 = User{id=1001, username='admin}
生命周期:4、初始化
生命周期:5、bean的后置处理器(初始化之后)com.example.bean.User#0 = User{id=1001, username='admin}
---------------------
生命周期:6、通过IOC容器获取bean并使用
---------------------
生命周期Person:1、创建对象
生命周期Person:2、依赖注入
生命周期:3、bean的后置处理器(初始化之前)com.example.bean.Person#0 = Person{id=10011, username='张三}
生命周期Person:4、初始化
生命周期:5、bean的后置处理器(初始化之后)com.example.bean.Person#0 = Person{id=10011, username='张三}
生命周期Person:6、通过IOC容器获取bean并使用
---------------------
生命周期:7、销毁
<!-- import -->
<import resource="bean.xml"/>
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。