pom.xml
<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.0modelVersion>
<groupId>com.lin.spring5groupId>
<artifactId>spring5_studyartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<modules>
<module>spring5_demo01module>
modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.1.1version>
dependency>
dependencies>
dependencyManagement>
project>
User.java
public class User {
public void add() {
System.out.println("add......");
}
}
bean1.xml
<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.lin.spring5.User">bean>
beans>
GlobalTest.java
/**
* @author Created by Lin Weihong
* @date on 2022/9/23 23:05
*/
public class GlobalTest {
@Test
public void testAdd() {
//1.加载spring的配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
//2.获取配置的对象
User user = applicationContext.getBean("user", User.class);
user.add();
}
}
输出结果
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
(2)使用 IOC 目的:为了耦合度降低
(3)做入门案例就是 IOC 实现
最终解耦方案:三者结合
1、IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
2、Spring提供IOC容器实现的两种方式:(两个接口)
(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用
加载配置文件时候就会把在配置文件对象进行创建,这种更适合web项目,因为这个过程很耗时,可以在tomcat启动的时候就加载这些对象,而不是用到了再加载
3、ApplicationContext 接口有实现类
ClassPathXmlApplicationContext
:对应src
FileSystemXmlApplicationContext
:对应系统盘符完整路径
1、什么是 Bean 管理
Bean 管理指的是两个操作
(1)Spring 创建对象
(2)Spirng 注入属性
(1)在 spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建
(2)在 bean 标签有很多属性,介绍常用的属性
id 属性:唯一标识
class 属性:类全路径(包类路径)
(3)创建对象时候,默认也是执行无参数构造方法完成对象创建
(1)DI:依赖注入,就是注入属性
(1)创建类,定义属性和对应的 set 方法
/**
* 演示使用 set 方法进行注入属性
*/
public class Book {
//创建属性
private String bname;
private String bauthor;
//创建属性对应的 set 方法
public void setBname(String bname) {
this.bname = bname;
}
public void setBauthor(String bauthor) {
this.bauthor = bauthor;
}
}
(2)在 spring 配置文件配置对象创建,配置属性注入
<bean id="book" class="com.atguigu.spring5.Book">
<property name="bname" value="易筋经">property>
<property name="bauthor" value="达摩老祖">property>
bean>
(1)创建类,定义属性,创建属性对应有参数构造方法
public class Orders {
//属性
private String oname;
private String address;
//有参数构造
public Orders(String oname, String address) {
this.oname = oname;
this.address = address;
}
}
(2)在 spring 配置文件中进行配置
<bean id="orders" class="com.atguigu.spring5.Orders">
<constructor-arg name="oname" value="电脑">constructor-arg>
<constructor-arg name="address" value="China">constructor-arg>
bean>
(1)使用 p 名称空间注入,可以简化基于 xml 配置方式
第一步 添加 p 名称空间在配置文件中
第二步 进行属性注入,在 bean 标签里面进行操作
<bean id="book" class="com.atguigu.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏">bean>
1、字面量
(1)null 值
(2)属性值包含特殊符号
<property name="address">
<value>>]]>value>
property>
bean>
2、注入属性-外部 bean
(1)创建两个类 service 类和 dao 类
(2)在 service 调用 dao 里面的方法
public class UserService {
//set方法注入
private UserDao userDao;//dao是接口,真正实现类是UserDaoImpl
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add() {
System.out.println("service....add......");
userDao.add();
//传统方法
// UserDao userDao = new UserDaoImpl();
// userDao.add();
}
}
(3)在 spring 配置文件中进行配置
<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="userService" class="com.lin.spring5.service.UserService">
<property name="userDao" ref="userDao"/>
bean>
<bean id="userDao" class="com.lin.spring5.dao.impl.UserDaoImpl">
bean>
beans>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean2.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.add();
}
3、注入属性-内部 bean
(1)一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门
部门是一,员工是多
(2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
<bean id="emp" class="com.lin.spring5.bean.Emp">
<property name="ename" value="小新">property>
<property name="gender" value="男">property>
<property name="dept">
<bean id="dept" class="com.lin.spring5.bean.Dept">
<property name="dname" value="开发部">property>
bean>
property>
bean>
@ToString
public class MyBean implements FactoryBean<Course> {
public Course getObject() throws Exception {
Course course = new Course();
return course;
}
public Class<?> getObjectType() {
return null;
}
public boolean isSingleton() {
return false;
}
}
@Test
public void testBeanFactory() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean3.xml");
Course course = applicationContext.getBean("myBean", Course.class);
System.out.println(course);
}
<bean id="myBean" class="com.lin.spring5.factorybean.MyBean">
bean>
设置多实例
<bean id="book" class="com.lin.spring5.collectiontype.Book" scope="prototype">
<property name="list" ref="bookList">property>
bean>
1、生命周期
(1)从对象创建到对象销毁的过程
2、bean 生命周期(没加后置处理器的)
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(4)bean 可以使用了(对象获取到了)
(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
代码演示:
@ToString
public class Orders {
private String oname;
public Orders() {
System.out.println("1.通过无参构造器创建bean的实例");
}
public void setOname(String oname) {
System.out.println("2.为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)");
this.oname = oname;
}
//创建初始化方法
public void initMethod() {
System.out.println("3.调用 bean 的初始化的方法(需要进行配置初始化的方法)");
}
//创建销毁方法
public void destroyMethod() {
System.out.println("5.bean销毁了");
}
}
<bean id="orders" class="com.lin.spring5.beanslife.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="手机">property>
bean>
@Test
public void testBeanLife() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean4.xml");
Orders orders = applicationContext.getBean("orders", Orders.class);
System.out.println("4.bean 可以使用了(对象获取到了)");
//销毁bean,close方法在子类ClassPathXmlApplicationContext中才有
applicationContext.close();
}
结果:
3、bean 生命周期(加后置处理器的)
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把bean实例传递给bean的后置处理器方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return null;
}
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把bean实例传递给bean的后置处理器方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return null;
}
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
代码演示:
<bean id="emp" class="com.lin.spring5.autowire.Emp" autowire="byType">bean>
<bean id="dept1" class="com.lin.spring5.autowire.Dept">bean>
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
* 上面四个注解功能是一样的,都可以用来创建 bean 实例
<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"
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
<context:component-scan base-package="com.lin.spring5"/>
beans>
//@Service//默认为userServiceImpl
@Service(value = "userService") //,如果不写value,默认是类名且首字母小写
public class UserServiceImpl {
public void add() {
System.out.println("UserServiceImpl...add...");
}
}
<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"
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
<context:component-scan base-package="com" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
context:component-scan>
<context:component-scan base-package="com">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
context:component-scan>
beans>
第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解
这个@Qualifier 注解的使用,和上面@Autowired 一起使用
@Value(value = “abc”)
package com.lin.spring5.service;
import com.lin.spring5.dao.UserDao;
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.Service;
import javax.annotation.Resource;
/**
* @author Created by Lin Weihong
* @date on 2022/9/24 20:31
*/
@Service//默认为userServiceImpl
//@Service(value = "userService") //,如果不写value,默认是类名且首字母小写
public class UserServiceImpl {
// @Autowired //根据类型进行注入
// //当UserDao有多个实现类的时候,不能在通过@Autowired注入,因为多个bean,没办法识别要用哪个,所以通过这个注解指定使用的bean名字
// @Qualifier(value = "userdao2")//这个value就是目标bean里面注解的value,没写就是默认类名首字母小写,必须搭配@Autowired使用
// private UserDao userDao;
// @Resource //按照类型注入,如果有多个实现类,这个方法也会报错的
@Resource(name = "userdao2")
private UserDao userDao;
@Value(value = "小新")
private String name;
public void add() {
userDao.add();
System.out.println("UserServiceImpl...add...");
System.out.println(name);
}
}
@Repository
public class UserDaoImpl implements UserDao {
public void add() {
System.out.println("UserDaoImpl...add...");
}
}
@Repository(value = "userdao2")
public class UserDaoImpl2 implements UserDao {
public void add() {
System.out.println("UserDaoImpl2...add...");
}
}
(1)创建配置类,替代 xml 配置文件
@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = {"com.lin.spring5"})
public class SpringConfig {
}
(2)编写测试类
@Test
public void fullAnnotation() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); //加载配置类
UserServiceImpl userServiceImpl = context.getBean("userServiceImpl", UserServiceImpl.class);
userServiceImpl.add();
}
println(“UserDaoImpl…add…”);
}
}
@Repository(value = “userdao2”)
public class UserDaoImpl2 implements UserDao {
public void add() {
System.out.println(“UserDaoImpl2…add…”);
}
}
##### 6、完全注解开发
(1)创建配置类,替代 xml 配置文件
```java
@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = {"com.lin.spring5"})
public class SpringConfig {
}
(2)编写测试类
@Test
public void fullAnnotation() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); //加载配置类
UserServiceImpl userServiceImpl = context.getBean("userServiceImpl", UserServiceImpl.class);
userServiceImpl.add();
}