1、入门案例
1.1、下载Spring5
下载地址:
https://repo.spring.io/ui/native/release/org/springframework/spring/
1.2、打开Idea工具,创建普通Java工程
1.3、导入 Spring5 相关 jar包
1.4、创建普通类,在这个类创建普通方法
package com.aiguigu.spring5;
public class User {
public void add(){
System.out.println("add......");
}
}
1.5、创建 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="user" class="com.aiguigu.spring5.User"></bean>
</beans>
1.6、进行测试代码编写
package testdemo;
import com.aiguigu.spring5.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
@Test
public void testAdd(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
user.add();
}
}
运行结果:
com.aiguigu.spring5.User@26a7b76d
add......
2、IOC 容器
什么是 IOC ?
1. 控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
2. 使用IOC目的:为了耦合度降低
2.1、IOC 底层原理
- xml解析、工厂模式、反射
原始方式调用类对象的方法:
工厂模式:
IOC 底层原理:
2.2、IOC 接口 (BeanFactory)
-
IOC 思想基于IOC容器完成,IOC容器底层就是对象工厂
-
Spring 提供 IOC容器实现两种方式:(两个接口)
1) BeanFactory:IOC 容器基本实现,是Sping 内部的使用接口,不提供开发人员进行使用
*加载配置文件时候不会创建对象,在获取对象(使用)才会创建对象
2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
*加载配置文件时候就会把对配置文件对象进行创建
2.3、IOC 操作 Bean 管理 (基于 xml )
- 什么是Bean 管理
1)Bean管理指的是两个操作
2)Spring创建对象
3)Spring 注入属性 - Bean 管理操作有两种方式
1)基于 xml配置文件方式实现
2)基于注解方式实现
基于 xml 方式创建对象:
<bean id="book" class="com.aiguigu.spring5.Book"></bean>
基于 xml方式注入属性:
- DI:依赖注入,就是注入属性
第一种注入方式:使用set方法 注入
第二种注入方式:使用有参构造进行注入
使用set方法 注入
package com.aiguigu.spring5;
public class Book {
private String name;
private String author;
public void setName(String name) {
this.name = name;
}
public void setAuthor(String author) {
this.author = author;
}
public void bookTest(){
System.out.println("name=" + name + ",author=" + author);
}
}
bean1.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="book" class="com.aiguigu.spring5.Book">
<property name="name" value="java入门"></property>
<property name="author" value="aiguigu"></property>
</bean>
</beans>
测试:
package testdemo;
import com.aiguigu.spring5.Book;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
@Test
public void testBook(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Book book = context.getBean("book", Book.class);
System.out.println(book);
book.bookTest();
}
}
运行结果:
com.aiguigu.spring5.Book@eb21112
name=java入门,author=aiguigu
Process finished with exit code 0
使用有参构造进行注入:
package com.aiguigu.spring5;
public class Orders {
private String name;
private String address;
public Orders(String name, String address) {
this.name = name;
this.address = address;
}
public void printOrder(){
System.out.println("name:" + name + "address" + address);
}
}
bean1.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="orders" class="com.aiguigu.spring5.Orders">
<constructor-arg name="name" value="ccc"></constructor-arg>
<constructor-arg name="address" value="china"></constructor-arg>
</bean>
</beans>
测试:
package testdemo;
import com.aiguigu.spring5.Orders;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
@Test
public void testOrders(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println(orders);
orders.printOrder();
}
}
运行结果:
com.aiguigu.spring5.Orders@eb21112
name:cccaddresschina
Process finished with exit code 0
简化注入 p注入:
FactoryBean
- Spring 有两种类型bean ,一种是普通bean,另一种工厂bean(FactoryBean)
- 普通 bean:在配置文件中定义 bean 类型就是返回类型
- 工厂 bean:在配置文件定义 bean 类型就可以和返回类型不一样
第一步:创建类,让这个类作为 工厂 bean,实现接口 FactoryBean
第二步:实现接口里面的方法,在实现的方法中定义返回的bean类型
代码实现
MyBean对象
package com.aiguigu.spring5.mybean;
import com.aiguigu.spring5.bean.Course;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
public class MyBean implements FactoryBean<Course> {
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCourseName("abc");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
xml 配置:
<bean id="myBean" class="com.aiguigu.spring5.mybean.MyBean"></bean>
test测试类:
@Test
public void testmyBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean6.xml");
Course course = context.getBean("myBean", Course.class);
System.out.println(course);
}
运行结果
Course{courseName='abc'}
bean 作用域
- 在 Spring 里面,设置创建 bean 实例是单实例还是多实例
- 在 Spring 里面,默认情况下,bean 是单实例对象
- 设置单实例或者多实例
1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单例还是多例
2)scope属性值
第一个值 sinleton(默认值),表示是单实例对象
第二个值 prototype,表示是多实例对象
<bean id="book" class="com.aiguigu.spring5.bean.Book" scope="prototype">
<property name="bookList" ref="bookList"></property>
</bean>
测试时创建两个对象输出两个对象
@Test
public void testBook2(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
}
运行结果:
com.aiguigu.spring5.bean.Book@5f71c76a
com.aiguigu.spring5.bean.Book@1d7acb34
- singleton 和 prototype 区别
1) singleton 单实例,prototype 多实例
2) 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象。
3)设置 scope值是 prototype 时候,不是在加载spring配置文件时候创建 对象,在调用 getBean方法时候创建多实例对象
bean 生命周期
- 生命周期
从对象创建到对象销毁的过程 - bean生命周期
1)通过构造器创建bean实例(无参构造)
2)为 bean 的属性设置值和对其他 bean 引用(调用 set方法)
3)调用 bean 的初始化的方法(需要进行配置初始化的方法)
4)bean 可以使用了(对象获取到了)
5)当容器关闭时候,调用了 bean 的销毁的方法(需要进行配置销毁的方法)
Orders对象
package com.aiguigu.spring5.bean;
import java.util.Map;
public class Orders {
private String oname;
public void setOname(String oname) {
System.out.println("第二步:调用set方法 设置值");
this.oname = oname;
}
public Orders() {
System.out.println("第一步:执行无参构造创建 bean 实例");
}
//创建执行的初始化方法
public void initMethod(){
System.out.println("第三步 执行初始化的方法");
}
public void destroyMethod(){
System.out.println("第五步 执行销毁的方法");
}
}
<?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="orders" class="com.aiguigu.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="java入门"></property>
</bean>
</beans>
运行结果
第一步:执行无参构造创建 bean 实例
第二步:调用set方法 设置值
第三步 执行初始化的方法
第四步 获取创建 bean 实例对象
com.aiguigu.spring5.bean.Orders@75881071
第五步 执行销毁的方法
- 后置处理器
1)通过构造器创建bean实例(无参构造)
2)为 bean 的属性设置值和对其他 bean 引用(调用 set方法)
3)把 bean实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
5)把 bean实例传递 bean 后置处理器的方法 postProcessAfterInitialization
6)bean 可以使用了(对象获取到了)
7)当容器关闭时候,调用了 bean 的销毁的方法(需要进行配置销毁的方法)
写一个类实现 BeanPostProcessor
package com.aiguigu.spring5.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行的方法");
return bean;
}
}
直接在xml配置文件里创建该对象,改对象对整个xml 的bean 都生效
<bean id="myBeanPost" class="com.aiguigu.spring5.bean.MyBeanPost"></bean>
运行结果
第一步:执行无参构造创建 bean 实例
第二步:调用set方法 设置值
在初始化之前执行的方法
第三步 执行初始化的方法
在初始化之后执行的方法
第四步 获取创建 bean 实例对象
com.aiguigu.spring5.bean.Orders@22eeefeb
第五步 执行销毁的方法
IOC操作 Bean管理(xml 自动装配)
- 什么是自动装配
根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入 - 自动装配过程
1)根据属性名字自动注入
2)根据属性类型自动注入
根据属性名字自动注入
<bean id="emp" class="com.aiguigu.spring5.bean.Emp" autowire="byType"></bean>
根据属性类型自动注入
<bean id="dept" class="com.aiguigu.spring5.bean.Dept" autowire="byType"></bean>
IOC 操作 Bean管理(外部属性文件)
-
引入德鲁伊连接池依赖 jar 包
-
创建外部属性文件,properties 格式文件,写数据库信息
-
把外部properties 属性文件引入到 spring 配置文件中
1)引入context 名称空间
2)在spring配置文件使用标签引入外部属性文件
引入context 名称空间
<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">
</beans>
在spring配置文件使用标签引入外部属性文件
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.userName}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>