Spring-Xml配置
一、Spring 简介
1.简介
-
文档下载地址:Index of /spring-framework/docs
1.简介
-
Spring framework 是 Spring 基础框架
-
学习Spring 家族产品
-
Spring framework
-
SpringBoot
-
SpringCloud
-
-
Spring 能用来做什么
-
开发 WEB 项目
-
微服务
-
分布式系统
-
-
Spring framework 是 Spring 最基础的框架,是其它框架技术的基础
-
SpringBoot 是用来做简化开发的,单一项目
-
SpringCloud 做分布式微服务相关的,拆分大单体项目为小模块项目
2.Spring 概述
2.1 Spring framework 介绍
-
概述:spring 提供了基础框架,你不必关心框架细节,只需要专注于代码业务逻辑
-
优点:
-
组件化模块化的:通过很多模块与组件组合成 spring 应用,以后可以通过 Xml 或者注解的方式去操作
-
控制反转( Inversion of Control (IoC) ):传统创建对象都是通过认为的new 对象的方式,把控制创建对象的权利转交给Spring
-
依赖注入(Dependency Injection):自动化的注入属性
-
3.模块
3.1 Spring 系统架构图

3.2模块介绍
-
Core Container:核心容器,是Spring 最核心的模块,以后用到的都依赖该模块实现
-
Aop:面向切面编程,目的是不改变原有代码的前提下对功能进行增强
-
Aspects:是Aop 具体实现
-
-
Data Access/Integration:数据层
-
Data Access:数据访问的
-
Data Integration:数据集成
-
Transactios:支持事务操作,通过 AOP 来实现,释放我们的双手
-
-
Web:WEB 层,SpringMVC 框架的
-
Servlet
-
Web
-
-
Test:做集成测试
-
整合 Junit 做单元测试
-
二、IOC
1.概述
-
IOC:Inversion of Control 控制反转,可以让容器负责对象的创建以及销毁操作,对象在容器中叫 bean
2.回顾问题
2.1问题:写了太多与业务无关的代码
-
耦合度非常高,写了很多和业务无关的代码
-
不利于项目的升级迭代
- 思考的解决方案
-
能够直接获取 mapper 接口,而不必去关心底层的获取方式
-

3.bean 配置
3.1.创建 spring01 项目
项目结构

添加 Spring 依赖
<dependencies>
<!-- 添加 spring 依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.17.RELEASE</version></dependency>
<!-- 添加 junit 依赖--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version>
<!-- <scope>test</scope>--></dependency></dependencies>
3.2添加 Student 类
- 创建空学生类
3.3添加 Spring 配置文件

开始配置 javabean
<?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 学生类--><bean id="student" name="stu" class="cn.sycoder.domian.Student"></bean>
</beans>
3.4属性介绍
| 属性名称 | 说明 |
|---|---|
| id | 给 bean 起名字(定义id 不能重复) |
| name | 给 bean 起别名 |
| class | 类全限定类名 |
4.容器创建
4.1ClassPathXmlApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
System.out.println(context);
4.2.FileSystemXmlApplicationContext
ApplicationContext ctx = new FileSystemXmlApplicationContext("绝对路径地址");
使用 ClassPathXmlApplicationContext 获取方式会出现如下问题

5.从容器中获取 bean
5.1根据id 获取
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//从容器中根据 id 获取 bean 对象
Student stu = (Student)context.getBean("student");//通过别名获取 bean 对象
Student stuByName = (Student)context.getBean("stu");
注意:如果id重复会有如下问题
5.2根据id和类型
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
final Student bean = context.getBean(Student.class);
注意:使用类型获取的时候,一定要保证容器中只有一个 javabean 对象

4.注意点
- bean 的配置spring 是使用反射调用对象的无参构造器实现的。所以必须提供无参构造器,否则会出现如下错误

6.设计模式
6.1单例模式
-
概述:属于创建型模式,提供了创建对象的最佳方式。单例模式只能有一个单一的类
-
懒汉式单例模式:需要用的时候,再去把对象创建出来
public class SingleObject {//线程不安全的懒汉式单例模式private static SingleObject instance;public static SingleObject getInstance(){if(instance == null){instance =new SingleObject();}return instance;}}
- 饿汉式单例模式:不管你有没有,我先创建出来
public class SingleObjectE {//线程不安全的饿汉式单例模式private static SingleObjectE instance = new SingleObjectE();public static SingleObjectE getInstance(){return instance;}
}
6.2工厂模式
-
概述:也是属于创建型模式,目的也是提供创建对象的最佳方式
-
静态工厂
public class BeanFactory {public static Student getBean() {return new Student();}public static Object getBean(String name) {if ("Student".equals(name))return new Student();else if("SingleObject".equals(name)) {return new SingleObject();}else{return new Object();}}}
- 实例工厂
public class BeanFactory {public Object getBean(){return new Student();}
}
7.bean 实例化
-
bean 交给 spring 创建,底层究竟是怎么创建的?
-
实例化 bean 三种方式:
-
构造器(常用)
-
静态工厂方法
-
实例工厂方法
-
实现 FactoryBean(最常用)
-
7.1无参构造器实例化
新建 person 类,底层是通过 clz.getDeclaredClasses() 获取构造器
public class Person {public Person(){}}
配置 Person bean
<bean id="person" class="cn.wjcoder.domian.Person"></bean>
从容器中获取 bean
@Test
public void testConstructorInit(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");Person p = (Person) context.getBean("person");}
注意:修改构造器,添加参数测试,提示找不到无参构造器


7.2静态工厂方法实例化
创建 clintServer 类,提供静态工厂方法
public class ClientServer {//创建自身对象并且私有化private static ClientServer clientServer = new ClientServer();private ClientServer() {}public static ClientServer createInstance(){return clientServer;}
}
配置bean 的 xml
<bean id="clientServer" class="cn.wjcoder.domian.ClientServer" factory-method="createInstance"></bean>
获取 bean
@Testpublic void testFactoryStaticMethodInit(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");final ClientServer bean = context.getBean(ClientServer.class);}

配置关系

7.3实例工厂方法实例化
创建实例工厂类
public class ClientServiceFactory {private static ClientService instance = new ClientService();private ClientServiceFactory(){}public ClientService getInstance(){return instance;}
}
public class ClientService {
}
配置 bean
<!-- 配置工厂--><bean id="clientFactory" class="cn.wjcoder.domian.ClientServiceFactory"></bean>
<!-- 配置 clientService--><bean id="clientService" factory-bean="clientFactory" factory-method="getInstance"></bean>
获取bean
@Testpublic void testFactoryInstanceMethodInit(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");final ClientService bean = context.getBean(ClientService.class);}
配置关系

7.4实现 FactoryBean实例化
创建员工类
public class Employee {public void check(){System.out.println("检查是否能够拿到员工类对象");}
}
创建员工 factory 类实现 FactoryBean
public class EmployeeFactory implements FactoryBean<Employee> {public Employee getObject() throws Exception {System.out.println("获取 emp 对象");return new Employee();}public Class<?> getObjectType() {return Employee.class;}public boolean isSingleton() {return false;}
}
配置工厂类(并没有直接配置 emp 类)
<bean id="employee" class="cn.wjcoder.domian.EmployeeFactory"></bean>
@Testpublic void testFactoryBeanInit(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");final Employee emp = (Employee)context.getBean("employee");emp.check();}
实现方法说明
-
isSingleton:如果是 true 返回单例的对象
public boolean isSingleton() {return true;}
- getObject:进行对象创建的
public Employee getObject() throws Exception {System.out.println("获取 emp 对象");return new Employee();
}
三、DI
1.概述
-
概述:Dependency Injection 依赖注入,给对象设置属性,曾经我们需要自己去创建 mapper 对象,才能调用,现在交给 spring 创建,并且使用 DI 注入,直接拿来用,程序员就可以更加关注业务代码而不是创建对象
-
给对象设置属性方式:
-
构造器
-
set 方法
-
-
spring 也是通过构造器以及set方法来实现属性设置
2.回顾问题
-
如果只给了 mapper 对象,那么调用的时候会出现空指针

解决方式:使用 DI 注入,解决方案如下

3.构造器依赖注入
3.1创建学生类
public class Student {
}
3.2创建Mapper 接口以及实现类
-
创建 Mapper 接口
public interface StudentMapper {void insert(Student stu);int delete(Long id); } -
创建 Mapper 实现类
public class StudentMapperImpl implements StudentMapper{public void insert(Student stu) {System.out.println("保存学生信息");} public int delete(Long id) {System.out.println("删除id="+id+"的学生信息");return 1;} } -
将 Mapper 交给容器管理
<bean id="studentMapper" class="cn.wjcoder.di.mapper.StudentMapperImpl"></bean>
3.3创建 service 接口以及实现类
-
创建 service 接口
public interface IStudentService {void insert(Student stu); int delete(Long id); } -
创建 service 实现类
public class StudentServiceImpl implements IStudentService { private StudentMapper mapper; public void insert(Student stu) {mapper.insert(stu);} public int delete(Long id) {return mapper.delete(id);} } -
将 service 交给容器管理
<bean id="iStudentService" class="cn.wjcoder.di.service.impl.StudentServiceImpl"></bean>
3.4如果没有使用DI注入直接调用
-
会产生如下问题

4.5配置构造器注入属性
配置 service 构造器
public class StudentServiceImpl implements IStudentService {private StudentMapper mapper;public StudentServiceImpl(StudentMapper mapper){this.mapper = mapper;}public void insert(Student stu) {mapper.insert(stu);}public int delete(Long id) {return mapper.delete(id);}
}
配置 xml
<!-- 配置 service--><bean id="iStudentService" class="cn.wjcoder.di.service.impl.StudentServiceImpl"><constructor-arg name="mapper" ref="studentMapper"></constructor-arg></bean>
<!-- 配置 mapper--><bean id="studentMapper" class="cn.wjcoder.di.mapper.StudentMapperImpl"></bean>
注意:
-
name:构造器的参数名称
-
ref:配置文件中其它 bean 的名称
-
图示如下

3.6构造器配置多个引用类型参数
配置service
public class StudentServiceImpl implements IStudentService {private StudentMapper mapper;private UserMapper userMapper;public StudentServiceImpl(StudentMapper mapper,UserMapper userMapper){this.mapper = mapper;this.userMapper = userMapper;}public void insert(Student stu) {mapper.insert(stu);}public int delete(Long id) {userMapper.delete(id);return mapper.delete(id);}
}
创建mapper
public interface UserMapper {int delete(Long id);
}
创建mapper实现类
public class UserMapperImpl implements UserMapper{public int delete(Long id) {System.out.println("删除id="+id+"的用户信息");return 1;}
}
配置bean
<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">
<!-- 配置 service-->
<bean id="iStudentService" class="cn.wjcoder.di.service.impl.StudentServiceImpl"><constructor-arg name="mapper" ref="studentMapper"></constructor-arg><constructor-arg name="userMapper" ref="userMapper"></constructor-arg>
</bean>
<!-- 配置学生mapper-->
<bean id="studentMapper" class="cn.wjcoder.di.mapper.StudentMapperImpl"></bean>
<!-- 配置用户mapper-->
<bean id="userMapper" class="cn.wjcoder.di.mapper.UserMapperImpl"></bean>
</beans>
3.7构造器配置多个基本数据类型参数
配置service
public class StudentServiceImpl implements IStudentService {private String name;private int age;private StudentMapper mapper;private UserMapper userMapper;public StudentServiceImpl(String name,int age,StudentMapper mapper,UserMapper userMapper){this.name = name;this.age = age;this.mapper = mapper;this.userMapper = userMapper;}public void insert(Student stu) {mapper.insert(stu);}public int delete(Long id) {System.out.println( name+":"+age);userMapper.delete(id);return mapper.delete(id);}
}
配置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">
<!-- 配置 service--><bean id="iStudentService" class="cn.sycoder.di.service.impl.StudentServiceImpl"><constructor-arg name="userMapper" ref="userMapper"></constructor-arg><constructor-arg name="mapper" ref="studentMapper"></constructor-arg><constructor-arg type="int" value="18"></constructor-arg><constructor-arg type="java.lang.String" value="sy"></constructor-arg></bean>
<!-- 配置学生mapper--><bean id="studentMapper" class="cn.sycoder.di.mapper.StudentMapperImpl"></bean>
<!-- 配置用户mapper--><bean id="userMapper" class="cn.sycoder.di.mapper.UserMapperImpl"></bean>
</beans>
这种方式会存在参数覆盖的问题,解决方式,删除 type 添加 index 属性
<?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">
<!-- 配置 service--><bean id="iStudentService" class="cn.sycoder.di.service.impl.StudentServiceImpl"><constructor-arg name="userMapper" ref="userMapper"></constructor-arg><constructor-arg name="mapper" ref="studentMapper"></constructor-arg><constructor-arg index="2" value="18"></constructor-arg><constructor-arg index="1" value="1"></constructor-arg><constructor-arg type="java.lang.String" value="sy"></constructor-arg></bean>
<!-- 配置学生mapper--><bean id="studentMapper" class="cn.sycoder.di.mapper.StudentMapperImpl"></bean>
<!-- 配置用户mapper--><bean id="userMapper" class="cn.sycoder.di.mapper.UserMapperImpl"></bean>
</beans>
4.setter依赖注入
-
使用 set 方法实现属性的注入
-
使用 property 属性
-
name:属性名称
-
value:直接给值
-
ref:其它bean的引用
-
4.1创建员工类
public class Employee {
}
4.2创建 mapper 接口以及实现类
-
mapper 接口
public interface EmployeeMapper {int delete(Long id); } -
mapper 实现类
public class EmployeeMapperImpl implements EmployeeMapper {public int delete(Long id) {System.out.println("删除当前员工id:"+id);return 1;} }
4.3创建 servie 接口以及实现类
-
创建 service 接口
public interface IEmployeeService {int delete(Long id); } -
创建 service 接口实现类
public class EmployeeServiceImpl implements IEmployeeService { private EmployeeMapper mapper; public int delete(Long id) {return mapper.delete(id);} }
4.4配置 setter 注入
-
配置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"><!-- 配置mapper实现类-->
<!-- 配置mapper--><bean id="empMapper" class="cn.sycoder.di.setter.mapper.EmployeeMapperImpl"></bean>
<!-- 配置service--><bean id="empService" class="cn.sycoder.di.setter.service.impl.EmployeeServiceImpl"></bean>
</beans>
-
service 实现中提供 mapper 的setter 方法
public class EmployeeServiceImpl implements IEmployeeService { private EmployeeMapper employeeMapper; public int delete(Long id) {return employeeMapper.delete(id);}public void setEmployeeMapper(EmployeeMapper employeeMapper){this.employeeMapper = employeeMapper;} } -
修改 beans.xml 通过 setter 注入
<?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"><!-- 配置mapper实现类--> <!-- 配置mapper--><bean id="empMapper" class="cn.sycoder.di.setter.mapper.EmployeeMapperImpl"></bean> <!-- 配置service--><bean id="empService" class="cn.sycoder.di.setter.service.impl.EmployeeServiceImpl"><property name="employeeMapper" ref="empMapper"></property></bean> </beans> -
获取 service 执行 delete 方法
@Testpublic void testSetDi(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("DiSetterBeans.xml");final IEmployeeService empService = (IEmployeeService) context.getBean("empService");empService.delete(2L);} -
setter 注入过程分析

4.5配置多个 setter 方法注入多个属性
-
给service 添加新的属性以及新的setter方法
public class EmployeeServiceImpl implements IEmployeeService { private EmployeeMapper employeeMapper; private UserMapper userMapper; public int delete(Long id) {return employeeMapper.delete(id);} public void setEmployeeMapper(EmployeeMapper employeeMapper){System.out.println("=======使用 setter 注入=======");this.employeeMapper = employeeMapper;} public void setUserMapper(UserMapper mapper){this.userMapper = mapper;} } -
配置 userMapper 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"><!-- 配置mapper实现类--> <!-- 配置mapper--><bean id="empMapper" class="cn.sycoder.di.setter.mapper.EmployeeMapperImpl"></bean> <!-- 配置service--><bean id="empService" class="cn.sycoder.di.setter.service.impl.EmployeeServiceImpl"><property name="employeeMapper" ref="empMapper"></property></bean> <!-- 配置 userMapper--><bean id="userMapper" class="cn.sycoder.di.constructor.mapper.StudentMapperImpl"></bean> </beans> -
通过 setter 注入
<?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"><!-- 配置mapper实现类--> <!-- 配置mapper--><bean id="empMapper" class="cn.sycoder.di.setter.mapper.EmployeeMapperImpl"></bean> <!-- 配置service--><bean id="empService" class="cn.sycoder.di.setter.service.impl.EmployeeServiceImpl"><property name="employeeMapper" ref="empMapper"></property><property name="userMapper" ref="userMapper"></property></bean> <!-- 配置 userMapper--><bean id="userMapper" class="cn.sycoder.di.constructor.mapper.UserMapperImpl"></bean> </beans> -
获取 service 操作delete 方法
@Testpublic void testSetterSDi(){final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("DiSetterBeans.xml");final IEmployeeService empService = (IEmployeeService) context.getBean("empService");empService.delete(2L);}
4.6使用 setter 注入简单类型
-
修改 service 类,提供两个属性 int age = 18,String name = "sy"
public class EmployeeServiceImpl implements IEmployeeService { private EmployeeMapper employeeMapper; private UserMapper userMapper;private String name;private int age;public void setName(String name){this.name = name;}public void setAge(int age){this.age = age;} public int delete(Long id) {System.out.println(name + ":" + age);userMapper.delete(id);return employeeMapper.delete(id);} public void setEmployeeMapper(EmployeeMapper employeeMapper){System.out.println("=======EmployeeMapper使用 setter 注入=======");this.employeeMapper = employeeMapper;} public void setUserMapper(UserMapper mapper){System.out.println("=======UserMapper使用 setter 注入=======");this.userMapper = mapper;} } -
配置 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"><!-- 配置mapper实现类--> <!-- 配置mapper--><bean id="empMapper" class="cn.sycoder.di.setter.mapper.EmployeeMapperImpl"></bean> <!-- 配置service--><bean id="empService" class="cn.sycoder.di.setter.service.impl.EmployeeServiceImpl"><property name="employeeMapper" ref="empMapper"></property><property name="userMapper" ref="userMapper"></property><property name="name" value="sy"></property><property name="age" value="18"></property></bean> <!-- 配置 userMapper--><bean id="userMapper" class="cn.sycoder.di.constructor.mapper.UserMapperImpl"></bean> </beans> -
可能出现的问题

4.7setter 注入总结
- 对于引用数据类型来说使用
<property name="" ref=""></property>
- 对于简单数据类型
*<property name="" value=""></property>
5.集合注入
List,Set,Map,Array,Properties
5.1添加CollectiosDemo类
1.添加CollectiosDemo类1.添加CollectiosDemo类public class CollectionsDemo {private List<Integer> list;private Map<String,String> map;private Set<String> set;private Properties properties;private int[] arr;public void print(){System.out.println("list:"+list);System.out.println("map:"+map);System.out.println("set:"+set);System.out.println("properties:"+properties);System.out.println("arr:"+ Arrays.toString(arr));}public void setList(List<Integer> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}public void setSet(Set<String> set) {this.set = set;}public void setProperties(Properties properties) {this.properties = properties;}public void setArr(int[] arr) {this.arr = arr;}
}
5.2配置 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"><bean id="collectionsDemo" class="cn.sycoder.collections.CollectionsDemo">
<!-- 注入 list--><property name="list"><list><value>1</value><value>2</value><value>3</value></list></property><property name="map"><map><entry key="name" value="sy"/><entry key ="age" value="18"/></map></property><property name="set"><set><value>just some string</value><value>just string</value></set></property><property name="properties"><props><prop key="url">@example.org</prop><prop key="user">root</prop><prop key="password">123456</prop></props></property><property name="arr"><array><value>2</value><value>2</value><value>2</value></array></property></bean>
</beans>
如果不提供setter 方法会出现如下错误

6.自动装配
6.1概述
-
概述:IOC容器根据bean所依赖的属性,自动查找并进行自动装配。
6.2分类
-
不启用自动装配
-
byName 通过名称
-
byType 通过类型
-
constructor 通过构造器
6.3实操
-
准备工作
public class EmployeeService {private EmployeeMapperImpl employeeMapper;public int delete(Long id) {return employeeMapper.delete(id);}public void setEmployeeMapper(EmployeeMapperImpl employeeMapper){System.out.println("=======EmployeeMapper使用 setter 注入=======");this.employeeMapper = employeeMapper;} } public class EmployeeMapperImpl{public int delete(Long id) {System.out.println("删除当前员工id:"+id);return 1;} } -
配置 bean 并且通过 bype 自动装配
<?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="empService" class="cn.sycoder.autowired.EmpService" autowire="byType"></bean><bean id="empMapperImpl" class="cn.sycoder.autowired.EmpMapperImpl"></bean> </beans> -
配置 bean 并且通过 byName 自动装配
<?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="empService" class="cn.sycoder.autowired.EmpService" autowire="byName"></bean><bean id="empMapperImpl" class="cn.sycoder.autowired.EmpMapperImpl"></bean> </beans> -
通过名称和类型的自动装配
-
byName
-
使用 id 或者是 name 别名
-
如果自动注入时,有多个相同对象,只能使用 byName
-
-
byType
-
根据类型注入
-
通过 byType 注入要保证容器中只有一个 bean 对象,否则会出现如下错误
-
-

- 注意:
-
自动注入的优先级是低于 setter 和 构造器注入的
-
自动注入只能用于引用类型,不能用于基本数据类型
-
推荐使用 byType 方式实现自动注入
-
注入流程
-
byType 根据 getClass 去注入
-
byName 根据属性名称去注入
-
-
7.bean scopes
- 常见的作用域
| 作用域 | 说明 |
|---|---|
| singleton | 单例的 |
| prototype | 多例 |
| request | 请求 |
| session | 会话 |
- 单例 singleton

- 修改对象变成多个实例的

-
注意:容器模式就是以单例的方式创建对象的,如果需要修改成非单例,使用 scope 属性修改即可
-
以后开发中适合将那些bean对象交给 spring 管理
-
持久层 mapper
-
业务层 service
-
控制层 controller
-
-
单例bean会出现线程安全吗
-
判断bean 对象是否存储数据,如果用来存储数据了,会导致线程安全问题
-
使用局部变量做存储,方法调用结束就销毁了,所以不存在线程安全问题
-
8.bean 生命周期
8.1概述
-
概述:生命周期就是一个对象从出生到死亡的过程
8.2使用用户类观察生命周期
-
创建用户类
public class User {private String name;public User(){System.out.println("构造器执行====");} public void setName(String name) {System.out.println("调用 set 方法");this.name = name;}public void init(){System.out.println("调用 init 方法");}public void destroy(){System.out.println("调用销毁方法");} } -
配置 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"><bean id="user" class="cn.sycoder.lifecycle.User" init-method="init" destroy-method="destroy"><property name="name" value="sy"></property></bean> </beans> -
获取 bean 出现如下问题,没有打印销毁方法
-
原因:
-
spring ioc 容器是运行在 jvm 虚拟机中的
-
执行 test 方法后 jvm 虚拟机开启,spring 加载配置文件创建 bean 对象,调用构造器以及 init 方法
-
test 方法执行完毕的时候, jvm 退出,spring ioc 容器来不及关闭销毁 bean,所以没有去调用 destroy 方法
-
-

- 解决办法,手动关闭容器

5.3BeanPostProcessor
- 自定义自己 bean 处理器
public class MyBeanPostProcessor implements BeanPostProcessor{public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//bean 前置处理器System.out.println("bean 的前置处理器");return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("bean 的后置处理器");//bean 后置处理器return 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.xsd"><bean id="user" class="cn.sycoder.lifecycle.User" init-method="init" destroy-method="destroy"><property name="name" value="sy"></property></bean><bean class="cn.sycoder.lifecycle.MyBeanPostProcessor"></bean>
</beans>
5.4生命周期总结
-
bean 对象创建(调用无参构造器)
-
设置属性通过 setter 方法
-
init 方法前调用 bean 的前置处理器
-
bean 的 init 方法
-
bean 的后置处理器
-
对象可以正常使用
-
destroy 销毁方法
-
ioc 容器关闭
-
jvm 虚拟机的退出
四、容器执行点
1.整合 druid 连接池
添加依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency>
1.1硬编码方式整合
新建德鲁伊配置
<?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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="username" value="root"></property><property name="password" value="123456"></property><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property></bean>
</beans>
注意:属性是通过 set 方法注入进来的
1.2使用占位符获取连接数据
- 建立 db.properties 配置文件
username=root
password=123456
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
- 配置引用db.properties
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"><property name="username" value="${username}"></property><property name="password" value="${password}"></property><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${url}"></property></bean>
<!-- 获取db.properties 配置文件--><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="db.properties"></property></bean>
- 引入 db.properties 缩写
<context:property-placeholder location="db.properties"/>
1.3注意事项
-
<context:property-placeholder location="db.properties"/> 使用这个标签加载配置会加载到电脑系统配置
- 解决方式
- 给配置文件加上前缀变量
jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
username=123
- 添加属性
<context:property-placeholder system-properties-mode="NEVER" location="db.properties"/>
- 加载多个配置文件可以用 * 代替
<context:property-placeholder system-properties-mode="NEVER" location="*.properties"/>
2.容器总结
2.1容器层级结构
- 按两次 shift 搜索 BeanFactory

- 按 ctrl + h 查看继承结构

2.2创建容器
-
BeanFactory 是容器顶层接口
-
ApplicationContext 核心接口
-
AbstractApplicationContext 抽象类,提供了获取 bean 以及加载资源的功能
-
ClassPathXmlApplicationContext 装载bean的,做初始化的
2.3bean 配置
<bean id="user" class="cn.sycoder.lifecycle.User" init-method="init" destroy-method="destroy" scope="默认单例" autowire="byName" lazy-init="false"><property name="name" value="sy"></property>
</bean>
-
lazy-init:如果开启懒加载,默认是调用时才创建bean
-
init-method:初始化方法
-
destroy-method:销毁方法
-
scope:作用域,单例,原型
-
autowire:自动注入
-
id:代表名称,必须唯一
-
class:全限定类名
2.4di 注入
- constructor-arg:构造器注入
- property : setter 注入
- 集合注入
相关文章:
Spring-Xml配置
一、Spring 简介 1.简介 文档下载地址:Index of /spring-framework/docs 1.简介 Spring framework 是 Spring 基础框架 学习Spring 家族产品 Spring framework SpringBoot SpringCloud Spring 能用来做什么 开发 WEB 项目 微服务 分布式系统 Spring framew…...
设计模式-工作线程 创建多少线程池合适
1、定义 让有限的工作线程(Worker Thread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现就是线程池,也体现了经典设计模式中的享元模式(重用对象)。 例如,海底捞的服务员(线程),轮流…...
【算法基础】深度优先搜索(DFS) 广度优先搜索(BFS)
一、DFS & BFS 1. 深度优先搜索DFS 深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。 2. 广度优先搜索BFS 广度优先搜索较之深度优先搜索之不同在于,深度…...
【分布式】ProtocolBuffer平滑升级原则
原文链接:https://blog.csdn.net/nash_cyk/article/details/99549719 关于Protocol Buffer优势这里就不详细介绍了,如便于不同开发语言的交互通信,便于服务器上线的平滑升级等。 但Protocol Buffer的Message协议升级是需要注意一些细节&…...
第四阶段17-关于Redis中的list类型,缓存预热,关于Mybatis中的`#{}`和`${}`这2种格式的占位符
关于Redis中的list类型 Redis中的list是一种先进后出、后进先出的栈结构的数据。 在使用Redis时,应该将list想像为以上图例中翻转了90度的样子,例如: 在Redis中的list数据,不仅可以从左侧压入,也可以选择从右侧压入…...
stringstream用法
stringstream是 C++ 提供的另一个字串型的串流(stream)物件,和之前学过的iostream、fstream有类似的操作方式。包含在头文件sstream中(#include <sstream>)。 实例: 1、C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能,即单纯性、类…...
2022年下半年系统集成项目管理工程师综合知识真题及答案解析
2022年下半年系统集成项目管理工程师综合知识真题及答案解析 1、()不属于“提升云计算自主创新能力”的工作内容。A.加强云计算相关基础研究、应用研究、技术研发、市场培育和产业政策密衔接与统筹协调B.引导大型云计算中心优先在能源充足、气候适宜、自然灾害较少的地区部…...
【洛谷 P2089】烤鸡(搜索)
烤鸡 题目背景 猪猪 Hanke 得到了一只鸡。 题目描述 猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 101010 种配料(芥末、孜然等)…...
Mac item2 配置免密登录开发机
1、配置 vi ~/.ssh/config 内容如下: Host * ControlMaster auto ControlPath ~/.ssh/master-%r%h:%p ControlPersist yes ServerAliveInterval 60 学习: ControlMaster #连接共享 ControlPath #与ControlMaster一起使用,指定连接共享的路径…...
vue 解决问题:Webpack安装不成功,webpack -v无法正常显示版本号
目录 一、解决问题:Webpack安装不成功,webpack -v无法正常显示版本号 二、解决问题: ERROR Error: Cannot find module webpack-log 三、 解决报错:error:03000086:digital envelope routines::initialization error 四、解决…...
07-1【openEuler】系统及进程管理(网络管理的补充实验及说明)
文章目录说在前面关于nmcli命令的使用使用nmcli命令修改主机IP地址1、运行ip addr列出openEuler20.03上的以太网卡2、列出当前活动的以太网卡3、开始分配静态IP地址(1)命令语法(2)将 IPv4 地址192.168.74.175分配给 ens33 网卡上&…...
【Linux】磁盘结构、文件系统、软硬链接、动静态库链接
文章目录1、磁盘结构1.1 磁盘的物理结构1.2 磁盘的存储结构1.3 磁盘的逻辑结构2、文件系统2.1 4KB加载到内存2.2 文件系统结构3、软硬链接3.1 软链接3.2 硬链接4、动静态库4.1 什么是库?4.2 静态库和静态库链接4.3 动态库和动态库链接4.4 动静态库的加载下面了解到&…...
交换机电口、光口、网络速率的基本概念总结
电口和光口千兆网 & 万兆网:POE:包转发率:背板带宽/交换容量:)电口和光口 电口: 电口也即RJ45口,插双绞线的端口(网线),一般速率为10M或100M,即为百兆工…...
【面试题 05.02. 二进制数转字符串】
来源:力扣(LeetCode) 描述: 二进制数转字符串。给定一个介于0和1之间的实数(如0.72),类型为double,打印它的二进制表达式。如果该数字无法精确地用32位以内的二进制表示࿰…...
webpack - webpack的基本使用和总结
文章目录1,webpack概念2,为什么学webpack3,webpack特点4,相对于其他工具优点5,准备工作6,webpack的核心介绍7,webpack使用 - 打包js代码8,打包css代码9,生成html文件10&a…...
【蓝桥杯嵌入式】定时器实现按键单击,双击,消抖以及长按的代码实现
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...
基于SSM的Javaweb爱心扶贫捐赠系统
文章目录 项目介绍主要功能截图:后台登录首页个人中心用户管理扶贫物资管理扶贫产品管理留言板管理前台前台首页扶贫产品新闻资讯留言板部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,…...
Spring Cloud(微服务)学习篇(三)
Spring Cloud(微服务)学习篇(三) 1 nacos中使用openFeign(调用方式)实现短信发送 1.1 在shop-sms-api中创建com.zlz.shop.sms.api.service/vo/dto/util,目录结构如下所示 1.2 在pom.xml(shop-sms-api)中加入如下依赖 <dependencies><dependency><groupId>…...
一文带你吃透JSP,增删改查实战案例详细解读
文章目录前言JSP 概述JSP快速入门搭建环境导入JSP依赖创建 JSP 页面编写代码测试JSP原理JSP 脚本实战案例JSP缺点发展阶段EL 表达式概述实战案例域对象JSTL 标签用法1用法2前言 不得不说,JSP 现在已经是一门十分老旧的技术了,学习编程时,不仅…...
taobao.item.propimg.upload( 添加或修改属性图片 )
¥开放平台基础API必须用户授权 添加一张商品属性图片到num_iid指定的商品中 传入的num_iid所对应的商品必须属于当前会话的用户 图片的属性必须要是颜色的属性,这个在前台显示的时候需要和sku进行关联的 商品属性图片只有享有服务的卖家(如&a…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

