Spring5学习详细笔记
- Spring学习总结 — 工厂
- Spring学习总结 — 工厂高级特性
- Spring学习总结 — AOP编程
- Spring学习总结 — 持久层整合
- Spring学习总结 — 注解编程
Spring学习总结 — 工厂
第一章 :引言
1. 什么是spring
spring是一个轻量级的JavaEE解决方案,整合了众多优秀的设计模式
-
轻量级
1.对于运行环境是没有要求的 tomcat resion jetty 2.代码移植性高 不需要实现额外的接口
-
JaveEE的解决方案
-
整合代理模式
1.工厂 2.代理 3.模板 4.策略![在这里插入图片描述](https://img-blog.csdnimg.cn/d7647e3b58d44942bd647c79402861ff.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5b2x5a2QbXM=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
2. 设计模式
1. 广义概念
面对对象设计中,解决特定问题的经典代码
2. 狭义概念
GOF4人帮定义的23中设计模式:工厂,适配器,门面,代理...
3. 工厂设计模式
3.1 什么是工厂设计模式
1. 概念:通过⼯⼚类,创建对象
User user = new User();
UserDAO userDAO = newUserDAOImpl();
2. 1. 好处:解耦合
2. 耦合:指定是代码间的强关联关系,⼀⽅的改变会影响到另⼀⽅
3. 问题:不利于代码维护
4. 简单:把接⼝的实现类,硬编码在程序中
UserService userService =new UserServiceImpl();
3.2 简单工厂的设计
package com.it.factory;
import com.it.service.UserService;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @Author muss
* @Date 2021/4/11 15:19
*/
public class BeanFactory {
private static final Properties properties =new Properties();
static {
try {
InputStream is = BeanFactory.class.getResourceAsStream("/application.properties");
properties.load(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static UserService getUserService() {
UserService userService = null;
try {
Class<?> aClass = Class.forName(properties.getProperty("userService"));
userService = (UserService) aClass.newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return userService;
}
}
3.3 通用工厂的设计
/**
*
* @param key 传入需要的对象对应的key
* @return 返回需要的对象
*/
public static Object getBean(String key){
Object object = null;
try{
object = Class.forName(key).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return object;
}
3.4 通用工厂的使用方法
1. 定义类型(类)
2. 通过配置文件的配置告知工厂(即application.properties)
key = value
3. 通过工厂获取了类的对象
Object object = BeanFactory.getBean(key);
4. 总结
Spring本质:工厂 ApplicationContext(applicationContext.xml)
第二章 :第一个的Spring程序
1. 软件版本
1. jDK1.8+
2. Maven 3.5+
3. IDEA 2020.3
4. SpringFramework 5.1.4
2. 环境搭建
-
Spring的jar包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.4.RELEASE</version> </dependency>
-
Spring的配置文件
1. 配置文件的放置位置:任意位置 没有硬性要求 2. 配置文件的命名:任意名字 推荐使用:applicationContext.xml
3. Spring的核心API
-
ApplicationContext
1. 作用:Spring提供ApplicationContext这个工厂是用于进行对象的创建 2. 好处:解耦合
-
ApplicationContext 接口类型
使用接口 :屏蔽实现的差异 非web环境下使用:ClassPathXmlApplicationContext (可以在main方法中,junit中使用) web环境下使用:XmlWebApplicationContext
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NxJCypr-1618670320032)(Spring5.assets/image-20210411160632964.png)]
-
重量级资源
1. ApplicationContext工厂的对象会占用大量的内存 2. 不会频繁的创建对象: 一般一个应用只会创建一个对象 3. ApplicaitonContext工厂:是 线程安全 的,所以可以多线程访问
-
4. 程序开发
1. 创建类型
2. 在配置文件applicationContext.xml, 中配置
<bean id="user" class="com.muss.bean.User"/>
3. 通过工厂类ApplicationContext,获取对象
ApplicationContext
|- ClassPathXmlApplicationContext
ApplicationContext ac = new ClassPathXmlApplicationContext(“/applicationContext.xml”)
5.细节分析
-
名词解释
Spring工厂创建的对象,叫做bean或者组件(Componet)
-
Spring工厂的相关方法
@Test public void test01() { ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml"); // 第一种获取bean的方法 User user = (User) ac.getBean("user"); // 第二种获取bean的方法 User user1 = ac.getBean("user", User.class); // 第三种获取bean的方法 !这种方法只能在配置文件中只配置了一个改类型的bean时生效,否则报错 User bean = ac.getBean(User.class); // 获取Spring工厂配置文件下所有bean标签的id值 String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println("beanDefinitionName= " + beanDefinitionName); } // 根据类型获取bean的id值 String[] beanNamesForType = ac.getBeanNamesForType(User.class); for (String s : beanNamesForType) { System.out.println("s= " + s); } // 用于判断是否存在有指定id值的bean,name属性的值不行 boolean user2 = ac.containsBeanDefinition("user"); System.out.println("boolean= " + user2); // 用于判断是否存在指定id的单例bean,name属性的值同样可以 boolean user3 = ac.containsBean("user"); System.out.println("boolean= " + user3); }
-
配置文件
1. bean标签中只配置class属性 <bean class="com.muss.bean.User"/> 1:如果没有id值的话,使用工厂对象的getBeanNamesForType方法时,返回的id值为系统默认的值,如com.muss.bean.User#01 2:这种配置方式的应用场景:如果这个bean只需要使用一次,那么就可以省略id值 如果这个bean会使用多次,或被其他bean引用的话则需要设置id值 2. bean标签中的name属性 作用:用在Spring的配置文件中,为bean对象定义别名(小名) 与id属性的异同: 相同:都可以使用工厂对象的getbean方法 ac.getBean("user") == ac.getBean("u1") 区别:别名可以定义多个且都有效,但id属性可以定义多个,但是只有第一个有效,其他的值会报错
6. Spring工厂的底层实现原理(简易版)
- 首先通过ClassPathXmlApplicationContext工厂读取配置文件 application.xml
- 获取配置文件中bean标签的相关信息 id值,class值
- 然后通过反射创建对象,底层会调用对象自己的构造方法 !Spring工厂不管是公共的还是私有的都可以调用
7. 思考
问题:是否在开发中所有的对象都会交给Spring工厂来创建?
回答:理论上是,但实际上实体对象(entity)是不会交给Spring来创建的,而是有持久层框架(mybatis)来创建
第三章 :Spring5与日志框架的整合
Spring与日志框架整合,日志框架就可以在控制台中,输出Spring框架运行过程中一些重要的信息
好处: 便于了解Spring框架运行过程,利于程序的调试
-
Spring整合日志框架
-
导入maven坐标
<!-- 日志框架所需的jar包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
引入配置文件
# 配置根 log4j.rootLogger=debug,console # 日志输出到控制台显示 log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern= %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
-
第四章 :注入(Injection)
1. 什么是注入
通过Spring工厂即配置文件,为所创建的对象的成员变量赋值
1.1 为什么需要注入
通过编码的方式,为成员变量赋值,存在耦合
1.2 如何进行注入
-
类的成员变量提供了setget方法
-
配置Spring的配置文件
<bean id="account" class="com.it.bean.Account"> <property name="id"> <value> 11 </value> </property> <property name="name"> <value> xiaojr </value> </property> </bean>
1.3 注入的好处
解耦合
2. Spring注入的原理分析(简易版)
Spring通过底层调用对象属性对应的set方法,完成对变量的赋值,这种方法也称为set注入
第五章 :Set注入详解
针对于不同的类型的成员变量,在<property>标签中,需要嵌套其他标签
1. JDK类型
1.1 JDK八大基本类型+String类型
<value>qiqi</value>
1.2 数组
<list>
<value>haha01@qq.com</value>
<value>haha02@qq.com</value>
<value>haha03@qq.com</value>
</list>
1.3 Set集合
<property name="tels">
<set>
<value>haha</value>
<list>
<value>aa</value>
<value>bb</value>
</list>
</set>
</property>
1.4 List集合
<list>
<value>aaa</value>
<set>
<value>01</value>
<value>02</value>
</set>
</list>
1.5 Map集合
注意:map --> entry --> key有特定标签<key></key>,值需要根据对应类型来选择标签
<map>
<entry>
<key>
<value>aaa</value>
</key>
<value>hhh</value>
</entry>
</map>
1.6 Properties类型
Porperties类型 是特殊的 Map类型 key=String,value=String
<props>
<prop key="a">aa</prop>
<prop key="b">bb</prop>
</props>
2. 用户自定义类型
2.1 第一种方法
-
为成员变量提供getset方法
-
配置文件中进行注入
<bean id="userService" class="xxxx.UserServiceImpl"> <property name="userDAO"> <bean class="xxx.UserDAOImpl"/> </property> </bean>
2.2 第二种方法
-
第⼀种赋值⽅式存在的问题
1. 配置⽂件代码冗余 2. 被注⼊的对象(UserDAO),多次创建,浪费(JVM)内存资源
-
为成员变量提供set get⽅法
-
配置⽂件中进⾏配置
<bean id="userDAO" class="xxx.UserDAOImpl"/> <bean id="userService" class="xxx.UserServiceImpl"> <property name="userDAO"> <ref bean="userDAO"/> </property> </bean> #Spring4.x 废除了 <ref local=