问什么要学Spring框架
1.简化开发---->降低企业级开发的复杂性(简化IOC控制反转,AOP面向切面编程,事务处理)
2.框架整合---->高效整合其他技术,提高企业级应用开发与运行效率
//整合mybatis,mybatisplus
Spring核心思想
1.解耦合,提高编写的程序的扩展性/灵活性
以前创建对象:new 构造方法 ,此方式耦合度非常高
// 实现的思想:
spring提供一个spring 容器(一个对象:内部包含一个集合,此集合中可以存放各种java对象)
spring可以帮助我们创建对象,不需要我们手动的通过new关键字创建对象
获取对象,直接找spring框架要对象既可
2.AOP面向切面编程,提供并实现了此思想,可以无入侵对代码功能进行增强
3.方便的整合第三方更加优秀的框架
4.提供了单元测试,方便测试
5.申明式事务,只需要一个事务注解就可以实现对指定的方法进行事务控制
6.内部体现了非常多的优秀的编程思想(学习一些优秀的设计理念/编程思想)
学习spring的源码
Ioc和Di
.ioc-->控制反转:我不创建对象,spring创建
ioc:以前程序员主动new对象,现在由外部spring创建对象, 解耦合,
底层原理:spring解析配置文件,扫描注解,反射无参构造方法创建对象
附:IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为-->Bean javabean
2.DI-->依赖注入:
附:类于类之间的关系
1.代理
2.聚合(依赖)
3.继承
在容器中建立绑定bean与bean之间的依赖关系的整个过程,称为依赖注入
// 注入:为spring管理的类的成员变量赋值
最终效果
使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
bean
IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为-->Bean
IOC入门问题
1. 管理什么?(Service与Dao)
2. 如何将被管理的对象告知IOC容器?(配置文件)
// <bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
3. 被管理的对象交给IOC容器,如何获取到IoC容器?(接口)
4. IOC容器得到后,如何从容器中获取bean?(接口方法)
5. 使用Spring导入哪些坐标?(pom.xml)
*ioc和di的标签
//ioc中出现
// <bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
// <bean id="BookService" class="com.itheima.service.impl.BookServiceImpl">
bean标签:表示配置bean
id属性:表示给bean起名字,为了好记,写接口名
class属性:表示给bean定义类型,直接写到实现类
//di注入时出现的
// <property name="bookDao" ref="BookDao"></property>
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体出现的属性,参照在service中的bookdao
ref属性:表示参照哪一个bean,写id的
附:bean 中 id是别名-->接口名 class-->直接具体实现了类
property中 name-->具体在service出现的 ref-->是写id
// 附:在bean中没写scope 默认singleton单例 可以调整prototype非单例
使用Spring模式和不使用spring模式区别
1.不用spring模式
new对象
//创建正常maven项目-->创建dao层和service层 及app测试类
//dao接口
public interface BookDao {
public void save();
}
//dao实现类
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
//service接口
public interface BookService {
public void save();
}
//service实现类
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
测试app
public class App {
public static void main(String[] args) {
//new service实现类 调用
BookServiceImpl bookService = new BookServiceImpl();
bookService.save();
}
}
输出语句:正常输出打印dao和service的语句
book service save ...
book dao save ...
2.使用spring的IOC入门
spring创建对象
1.导入spring在pom文件的依赖
记得加个jdk版本的
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
2.在resources下创建applicationContext.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标签:表示配置bean
id属性:表示给bean起名字,为了好记,写接口名
class属性:表示给bean定义类型,直接写到实现类
-->
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="BookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
</beans>
3.创建app2测试类
public class App2 {
public static void main(String[] args) {
//1.创建配置类-->加载配置类
ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取bean对象 参数写application里面的id 类型转换
BookService bookService = (BookService) ct.getBean("BookService");
bookService.save();
}
}
输出:
book service save ...
book dao save ...
使用spring好处
如果频繁修改测试app的BookDaoImp类
不使用spring--->用自己new对象的方式,发现BookDaoImpl类名改变,测试类也需要修改代码
用spring框架方式--->发现BookDaoImpl类名改变,测试类无需修改代码(只需要修改配置文件),完成解耦
3.DI入门案例
理解di思路
1. 基于IOC管理bean
2. Service中使用new形式创建的Dao对象是否保留?(否)
3. Service中需要的Dao对象如何进入到Service中?(提供set方法)
4. Service与Dao间的关系如何描述?(配置) 绑定DAO和Service关系
//<property name="bookDao" ref="BookDao"></property>
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性,参照在service中的bookdao 一般小写
ref属性:表示参照哪一个bean,写id的
实现步骤
【第一步】删除使用new的形式创建对象的代码
【第二步】提供依赖对象对应的setter方法
【第三步】在applicationContext配置service与dao之间的关系
代码实现
在service实现类中
public class BookServiceImpl implements BookService {
// private BookDao bookDao = new BookDaoImpl();
//1. 删除new方法 重写接口
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
//2.提供set方法
//右键setter方法
//spring框架会反射执行该方法,为成员变量赋值
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
在applicationContext.xml中 进行di注入
<?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属性:表示给bean起名字,为了好记,写接口名
class属性:表示给bean定义类型,直接写到实现类
-->
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="BookService" class="com.itheima.service.impl.BookServiceImpl">
<!--配置server与dao的关系
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性,参照在service中的bookdao
ref属性:表示参照哪一个bean,写id的
-->
<property name="bookDao" ref="BookDao"></property>
</bean>
</beans>
4.bean实例化
(报错的话,从最后面看错误信息 ,上面都是一样的 从下往上看)
bean是如何创建出来的(bean的实例化三种方式)
bean本质是对象 ,以前都是有构造方法 在new bean(就是new 对象)
1.构造方法创建对象
spring创建bean对象 采用的是无参构造
例:在实现类中提供无参构造,如果写有参 必须写无参 ,不写无参和有参,默认无参
// 右键 generate-->constuctor 不选定方法->无参 选定方法-->有参
privateStudent(){}
publicStudent(){}
注意:无参构造方法如果不存在,将抛出异常BeanCreationException
2.静态工厂方式
使用静态方法-->静态工厂
了解
3 实例工厂方式
了解 资料有详细的
5.bean生命周期
bean创建到销毁的过程
6.DI注入方式
1.setter注入
提供set方法,spring框架会反射执行该方法,为成员变量赋值
2.构造方法注入
1.在serviceimpl设置有参构造和无参构造
2.提供set方法,spring框架会反射执行该方法,为成员变量赋值
7.自动装配依赖
自动创建对象 dao或者service
如果一个类是自动装配 的
1.则用spring获取该类的对象时,可以不指定id,直接指定类型即可
2.其成员变量会自动赋值,无需配置成员变量
app2
dao接口
public interface BookDao {
public void save();
}
dao实现类
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
service接口
public interface BookService {
public void save();
}
service实现类
public class BookServiceImpl implements BookService {
// private BookDao bookDao = new BookDaoImpl();
//1. 删除new方法 重写接口
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public BookServiceImpl() {
}
//2.提供set方法
//右键setter方法
//spring框架会反射执行该方法,为成员变量赋值
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
public class App2 {
public static void main(String[] args) {
//1.创建配置类-->加载配置类
ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取bean对象 参数写application里面的id 类型转换
/*BookService bookService = (BookService) ct.getBean("BookService");
bookService.save();*/
BookService bean = ct.getBean(BookService.class); //通过类型找到对象
System.out.println(bean);
bean.save();
}
}
applicationContext.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标签:表示配置bean
id属性:表示给bean起名字,为了好记,写接口名
class属性:表示给bean定义类型,直接写到实现类
autowire="byType" 直接自动装配 依赖注入
-->
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="BookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType">
第三方资源配置管理
1.管理DataSource的Druid和c3p0连接池
1. 管理Druid连接池
用set注入 德鲁伊和c3p0 在applicationContext.xml中的4大金刚(数据库名字,数据库路径,用户名,密码,)稍微不一样
【第一步】添加Druid连接池依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
注意:除了添加以上两个依赖之外,别忘了添加spring-context依赖
【第二步】配置DruidDataSource连接池Bean对象
注意id 测试类需要用
<beanid="dataSource"class="com.alibaba.druid.pool.DruidDataSource">
<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
<propertyname="url"value="jdbc:mysql://localhost:3306/spring_db"/>
<propertyname="username"value="root"/>
<propertyname="password"value="320321"/>
</bean>
【第三步】在测试类中从IOC容器中获取连接池对象并打印
publicclassApp {
publicstaticvoidmain(String[] args) {
ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext.xml");
DataSourcedataSource= (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
2.管理c3p0连接池
【第一步】添加c3p0连接池依赖
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
【第二步】配置c3p0连接池Bean对象
<beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource">
<propertyname="driverClass"value="com.mysql.jdbc.Driver"/>
<propertyname="jdbcUrl"value="jdbc:mysql://localhost:3306/spring_db"/>
<propertyname="user"value="root"/>
<propertyname="password"value="320321"/>
<propertyname="maxPoolSize"value="1000"/>
</bean>
注意:同一个Spring容器中不能有两个id="dataSource"的连接池。
【第三步】在测试类中从IOC容器中获取连接池对象并打印
publicclassApp {
publicstaticvoidmain(String[] args) {
ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext.xml");
DataSourcedataSource= (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
加载properties属性文件
大体思路
不要使用user name 系统默认是电脑自己的用户名字
1.加载第三方配置 //为了防止乱码写英文
2.创建接口
3.创建接口实现类 并加注解@data提供setget方法
4.创建applicatonContext.xml配置文件
(1.)通过
<context:property-placeholderlocation="sanguo.properties"system-properties-mode="NEVER"/> 获取beans
(2.)通过 propertyname和value${}获取键值
5.创建app测试类-->加载配置类-->通过接口.class获取bean-->输出
读取第三方配置文件案例
1.加载第三方配置文件 三国.proerties
junshi=zhugege
jaingju=Tom
zhugong=dogdog
创建dao
public interface SanGuo {
}
创建dao实现类
@Data //注解 自动补全 get set 有参 空参 构造
public class SanGuoImpl implements SanGuo {
private String junshi;
private String jiangjun;
private String zhujun;
}
3.创建主配置文件
aplicationContext.xml
1.在配置文件中使用<propertyname="xxx"value=""></property> 加载第三方的name
2.引入第三方的 配置不加载系统属性
<context:property-placeholderlocation="jdbc.properties"system-properties-mode="NEVER"/>
3.使用${}获取第三方文件的value值
value="${junshi}"
完整的配置文件
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholderlocation="sanguo.properties"system-properties-mode="NEVER"/>
<beanid="SanGuoImpl"class="com.itheima.dao.impl.SanGuoImpl">
<propertyname="junshi"value="${junshi}"></property>
<propertyname="zhujun"value="${zhugong}"></property>
<propertyname="jiangjun"value="${jaingju}"></property>
</bean>
</beans>
6.编写测试类
publicclassApp2 {
publicstaticvoidmain(String[] args) {
//1.创建配置类-->加载配置类
ClassPathXmlApplicationContextct=newClassPathXmlApplicationContext("applicationContext.xml");
//2.获取bean对象 参数写application里面的id 类型转换
SanGuobean=ct.getBean(SanGuo.class); //通过接口类找到对象
System.out.println(bean);
}
}
输出
SanGuoImpl(junshi=zhugege, jiangjun=Tom, zhujun=dogdog)
附加知识
<context:property-placeholder location="classpath*:*.properties"/>