Spring
概念
- 是一个轻量级的框架
- 也是一个容器,用来存放需要使用的对象。
作用:
- 提高开发效率
- 增强可重用性
- 提供编写规范
- 节约维护成本
- 解耦底层实现原理
Spring体系结构
- 底层是核心容器
- Beans
- Core
- Context
- SpringEl表达式
- 中间层技术
- AOP
- Sspects
- 应用层技术
- 数据访问于数据集成
- Web集成
- Web实现
- 基于Test测试
Spring_Ioc(控制反转)
- 作用:本质上就是一个容器,这个容器里面存放当前系统所需要的的类对象
Bean标签属性
-
id:唯一表示(map的key)
-
class:指定当前需要创建对象的全限定类名
-
name:起别名,多个别名之间用逗号隔开
<bean id="userService" name="userService1,userService2" class="com.itheima.service.imp.UserServiceImp"/>
效果
-
scope:[默认spring中的bean是单列]
-
singleton单列,单列容器中当前实例对象永远只有一个,在读取配置文件的时候就会创建并且存储到内存中
<bean id="userService" scope="singleton" name="userService1,userService2" class="com.itheima.service.imp.UserServiceImp"/>
-
prototype 多列,多列容器不会存储对象,而是每次使用创建一个新的
<bean id="userService" scope="prototype" name="userService1,userService2" class="com.itheima.service.imp.UserServiceImp"/>
-
效果
- init_method
- 在构造方法执行完成后执行的初始化方法
- destroy—method
- 关闭spring执行关闭方法,单列模式需要关闭容器,才会执行。如果是多列模式不会执行这个destroy-method方法
配置Bean的方法
- 普通bean配置(id,class),直接反射创建bean放入容器
- 第三方工具有些类不能够直接通过new的方式创建bean
静态工厂配置bean
- 创建bean的方法是静态方法,不用创建工厂对象
案例
package com.itheima.service.factory;
import com.itheima.service.imp.UserServiceImp;
/*
这是一个工厂类
*/
public class Userfactory {
//获取一个UserServiceImp对象
public static UserServiceImp getUser(){
return new UserServiceImp();
}
}
userServiceImp
package com.itheima.service.imp;
import com.itheima.service.User;
public class UserServiceImp implements User {
public UserServiceImp(){
System.out.println("创建了此对象");
}
@Override
public void save() {
System.out.println("run spring ...");
}
}
映射配置文件
<!--静态工厂创建方法 factory-method:工厂对象中获取ServiceImp对象的方法-->
<bean id="userService1" class="com.itheima.service.factory.Userfactory" factory-method="getUser"/>
测试代码和效果
public class User_Factory {
public static void main(String[] args) {
//1,读取spring核心配置文件
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过工厂模式来获取UserServiceImp对象
UserServiceImp userService1 = (UserServiceImp) ctx.getBean("userService1");
userService1.save();
}
}
流程图
实例工厂配置bean
- 工厂类中获取对象的方法不是静态的
案例
工厂类:方法是非静态方法
package com.itheima.service.factory;
import com.itheima.service.imp.UserServiceImp;
/*
实例工厂类
*/
public class User_Factory1 {
//获取userServiceImp的方法
public UserServiceImp getUserService(){
return new UserServiceImp();
}
}
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">
<!--通过实例对象创建 1.创建工厂对象 相当于new User_Factory1()-->
<bean id="userFactory" class="com.itheima.service.factory.User_Factory1"/>
<!--2.调用里面的方法 factory-bean:表示工厂对象 factory-method:工厂对象中获取到ServiceImp对象的方法-->
<bean id="userFactory1" factory-bean="userFactory" factory-method="getUserService"/>
</beans>
测试代码
package com.itheima.service;
import com.itheima.service.imp.UserServiceImp;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class User_Factory {
public static void main(String[] args) {
//1,读取spring核心配置文件
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过工厂模式来获取UserServiceImp对象
UserServiceImp userService1 = (UserServiceImp) ctx.getBean("userFactory1");
userService1.save();
}
}
结果:
流程图
Spring_HelloWord
-
加载spring(导入maven坐标)
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies>
-
配置文件(你需要存储那些对象到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"> <!-- id:这个这个bean取个名字 Class:接口实现类的全路径 name:别名,多个别名之间用逗号隔开 --> <bean id="userService" name="userService1,userService2" class="com.itheima.service.imp.UserServiceImp"/> </beans>
-
创建容器对象
ApplicationContext ctx=new ClassPathXmlApplicationContext("配置文件名");
UserService userService=(UserService)ctx.getBean("userService");
4. 根据id获取容器中的对象
UserService userService=(UserService)ctx.getBean("userService");
userService.save();
依赖注入
- 作用:给对应的成员变量添加属性值
set依赖方式注入
- 给需要属性注入的类添加setter方法
- 到配置文件中使用property标签
- property的属性:
- name:成员变量的名字
- values:普通类型设置的值
- ref:spring已经配置好的值
案例
/*
user对象中有两个属性:
name-普通类型
Person-应用类型
*/
public class UserServiceImp implements User {
private String name;
private Person person;
public void setName(String name) {
this.name = name;
}
public void setPerson(Person person) {
this.person = person;
}
public UserServiceImp(){
System.out.println("创建了此对象");
}
@Override
public void save() {
System.out.println("run spring ...");
}
}
配置文件
<!--Person-->
<bean id="person" class="com.itheima.service.imp.PsersonImp"/>
<!--依赖注入
name:对象中属性的变量名
value:普通类型赋值用value
ref:引用数据类用ref 例:person是一个对象,new这个对象在spring中必须是配置了的
-->
<bean id="user1" class="com.itheima.service.imp.UserServiceImp">
<property name="name" value="cxk"/>
<property name="person" ref="person"/>
</bean>
流程图
构造器注入
- 在对应的类中生成构造方法
- 在bean标签下面使用constructor-arg标签来指定对应参数的值
- name :指定参数名
- index:指定参数的索引
- value:设置普通值
- ref:设置一个引用值(spring中配置了的)
代码
配置文件
<!--依赖注入-构造方法-->
<bean id="student" class="com.itheima.dao.Student">
<!--
name:表示实体类中的属性名
value:表示要赋值的内容
ref:如果属性是一个应用类型需要是用ref
-->
<constructor-arg name="name" value="cxk"/>
<constructor-arg name="gender" value="nv"/>
</bean>
实体类
public class Student {
private String name;
private String gender;
public void setName(String name) {
this.name = name;
}
public void setGender(String gender) {
this.gender = gender;
}
public Student(String name, String gender) {
this.name = name;
this.gender = gender;
}
}
集合注入(Properties比较常用)
需求:
给StudentServiceImp类中的成员变量赋值
public class StudentServiceImp implements StudentService {
private int[] ints;
private List<String> list;
private Map<String,String> map;
public void setInts(int[] ints) {
this.ints = ints;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public void save() {
System.out.println("运行");
}
}
配置文件内容
<bean id="studentService" class="com.itheima.dao.imp.StudentServiceImp">
<!--
数组:<array>
<value>值1</value>
<value>值2</value>
...
</array>
-->
<property name="ints">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<!--
集合:<list>
<value>值1</value>
<value>值2</value>
...
</list>
注意:值得内容需要和list的泛型保持一致
-->
<property name="list">
<list>
<value>cls</value>
<value>cxk</value>
<value>红莲</value>
</list>
</property>
<!--
Map:<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
<entry key="k3" value="v3"/>
</map>
注意:值得内容需要和map的泛型保持一致
-->
<property name="map">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
<entry key="k3" value="v3"/>
</map>
</property>
<!--
Set:<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
-->
<property name="myset">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<!--
Propertie:<properties>
<props>
<porp key="k1">v1</prop>
<porp key="k2">v2</prop>
<porp key="k3">v3</prop>
...
</props>
</properties>
-->
<property name="properties">
<props>
<prop key="username">张三</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
注意:如果集合中的泛型是一个引用数据类型,value替换成values-ref
效果
p命名空间的引入和使用(了解)
#### 普通的set注入
<!--使用set注入-->
<bean id="studentService1" class="com.itheima.dao.imp.StudentServiceImp">
<property name="name" value="张三"/>
</bean>
P使用
<!--使用p标签注入-->
<bean id="studentService2" class="com.itheima.dao.imp.StudentServiceImp" p:name="李四"></bean>
但是使用p属性需要在头文件中的xmlns:xsi下面上xmlns:P
xmlns:p="http://www.springframework.org/schema/p"
EL表达式(了解)
<!--EL表达式-->
<bean id="studentService3" class="com.itheima.dao.imp.StudentServiceImp">
<property name="name" value="#{'666'}"/>
</bean>
将原来的内容替换成${}的形式
property
-
编写properties文件放在resources目录下
testName=root password=123
-
添加头文件
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"
-
扫描文件
<context:property-placeholder location="classpath:test.properties"/>
-
${}获取值
bean id="user2" class="com.itheima.dao.User2"> <property name="userName" value="${testName}"/> <property name="password" value="${password}"/> </bean>
效果:
import标签
-
加载配置文件是在主配置文件,对应的key可以在子配置文件中使用,idea爆红无所谓
-
context:property-placeholder 此标签最好只出现一次
-
<import resource="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:p="http://www.springframework.org/schema/p"
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">
<!--包含其它的配置文件-->
<import resource="Proson.xml"/>
</beans>
被引入的配置文件
<?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="person" class="com.itheima.dao.imp.Person">
<property name="name" value="张三"/>
<property name="gender" value="女"/>
</bean>
</beans>
java代码
public class listTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);
}
}
效果
配置文件的方式整合Mybatis
步骤
- 配置数据库连接信息 DruidDataSource
<!--读取src下面的数据库连接信息-->
<context:property-placeholder location="classpath:*.properties"/>
<!-- 配置数据库连接信息-->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
<!---配置驱动信息-->
<property name="driverClassName" value="${jdbc.driver}"/>
<!--配置链接地址-->
<property name="url" value="${jdbc.url}"/>
<!--配置用户名-->
<property name="username" value="${jdbc.username}"/>
<!--配置数据库连接密码-->
<property name="password" value="${jdbc.password}"/>
</bean>
- 配置SqlSessionFactoryBean对象
<!--配置SqlSessionFactoryBean对象-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--配置别名-->
<property name="typeAliasesPackage" value="com.itheima"/>
<!--读取配置信息-->
<property name="dataSource" ref="datasource"/>
</bean>
- 配置映射配置文件,使用dao接口的代理实现类 MapperScannerConfigurer
<!--配置映射配置文件的或注解方式,实现接口的对象 MapperScannerConfigurer-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描接口映射配置文件的路径-->
<property name="basePackage" value="com.itheima.dao"/>
</bean>
- 配置业务层,并属性注入值
<!--配置Service层对象-->
<bean id="studentServiceImp" class="com.itheima.Service.imp.StudentServiceImp">
<!--给service层属性注入值 上面已经实现了接口的代理对象,这里的值就是接口名首字母小写-->
<property name="studentDao" ref="studentDao"/>
</bean>