狂神说Java --- 记录Spring学习笔记
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了狂神说Java --- 记录Spring学习笔记相关的知识,希望对你有一定的参考价值。
☞传送门 ==>B站遇见狂神说—Spring5教程
感谢狂神,学习视频真的是通俗易懂♥♥♥
笔记和练习只是跟着视频整理的;有的知识点并没有整理进来
Spring 官网==>https://spring.io
Spring官方文档==>https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
本次使用的是Spring Web MVC
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
之后还可能用到spring jdbc
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
1.Spring概述
Spring是开源免费的轻量级的控制反转(IOC)和面向切面(AOP)的容器框架;支持事务处理.
由7个模块组成,
(Spring Boot) 构建一切,(Sprint Cloud)协调一切,(Spring Cloud Data Flow)连接一切
(Spring Boot)就像脚手架,可实现快速开发单个微服务;而学习它的前提是学习Spring和SpringMVC.
2. 控制反转IOC
IOC理论推导
创建一个空的maven项目,删除src目录;作为父级项目;
还是和之前一样,先去检查maven地址;
在pom.xml
导包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<!--测试使用-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
可看到,下载结束后,出现了好几个资源包
创建一个子级maven工程;
就用一个基础的项目构建来说吧;
持久层接口UserDao
;
public interface UserDao {
//查询用户;
void findUser();
}
持久层实现类UserDaoImpl
;
public class UserDaoImpl implements UserDao{
public void findUser() {
System.out.println("默认调用的方法");
}
}
业务层接口UserService
;
public interface UserService {
//查询用户;
void findUser();
}
业务层接口的实现类UserServiceImpl
;
public class UserServiceImpl implements UserService{
private UserDao userDao=new UserDaoImpl();
public void findUser() {
//在业务层调用持久层的方法;
userDao.findUser();
}
}
测试调用
@Test
public void test(){
UserService userService=new UserServiceImpl();
userService.findUser();
}
这时输出
而如果说,这时候又来需求了,持久层新增了一个实现类UsermysqlImpl
public class UserMySqlImpl implements UserDao{
public void findUser() {
System.out.println("MySql的方法");
}
}
那么如果说想要拿到这个需求的实现,就要在业务层的实现类UserServiceImpl
中;去更改持久层的实现类改为UserMySqlImpl
;
public class UserServiceImpl implements UserService{
private UserDao userDao=new UserMySqlImpl();
public void findUser() {
//在业务层调用持久层的方法;
userDao.findUser();
}
}
测试调用,即可
如果说又有一个新的需求,创建了一个新的持久层实现类UserOracleImpl
;
public class UserOracleImpl implements UserDao{
public void findUser() {
System.out.println("Oracle方式");
}
}
那么就得去业务层UserServiceImpl
中更改;
public class UserServiceImpl implements UserService{
private UserDao userDao=new UserOracleImpl();
public void findUser() {
//在业务层调用持久层的方法;
userDao.findUser();
}
}
然后测试调用
在之前的业务中,用户的需求可能会影响原来的代码,就要根据用户的需求更改代码.
要是在UserServiceImpl
中用set实现动态修改实现类;
public class UserServiceImpl implements UserService{
private UserDao userDao;
//控制反转的原型,在业务层提供动态的用户需求方法;
//用set实现动态注入值;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void findUser() {
//在业务层调用持久层的方法;
userDao.findUser();
}
}
在测试执行的方法内,只需要调用setUserDao
方法,去更改里面的持久层实现类即可
public class MyTest {
@Test
public void test() {
UserService userService = new UserServiceImpl();
((UserServiceImpl) userService).setUserDao(new UserMySqlImpl());
userService.findUser();
}
}
每使用set设置之前,程序是需要主动创建对象,控制权在开发者手中,使用了set注入后,程序不再具有主动性,变为被动的接受对象.
开发者不必管理对象的创建,系统耦合性降低,专注于业务的实现.
即控制反转 IOC 的原型.
IOC的本质
控制反转IOC 设计思想,而 DI(依赖注入)是实现IOC的一种方法,
在没有使用IOC的程序,作为面向对象编程的语言,对象的创建和对象间的依赖关系
是必须硬编码在程序中,对象的创建由程序自己控制,
控制反转后将对象的创建转移到第三方, 获取依赖对象的方式反转.
3.试试Spring
ok新建一个实体类User
;
public class User {
private String name;
public User(){
System.out.println("User类的无参构造");
}
public User(String name){
this.name=name;
System.out.println("User类的有参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\\'' +
'}';
}
}
在resources
目录下创建beans.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-3.0.xsd">
<!--使用spring 创建对象;就是 bean-->
<!--这时的id就是变量名;class就是new的对象-->
<!--property: 可以为对象的属性设置值-->
<bean id="user" class="com.lzq.pojo.User">
<property name="name" value="xiaozhi"/>
</bean>
</beans>
测试
public class Test01 {
public static void main(String[] args) {
//获取Spring得上下文对象;
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//由于创建对象就是 Spring 中的bean; 获取bean即可获取对象;
User user = (User) context.getBean("user");
System.out.println(user.toString());
}
}
输出:
User类的无参构造
User{name='xiaozhi'}
可以看出,从始至终没有使用new构造方法进行创建User类的对象;
但是实际上在xml配置文件中,已经被Spring创建对象了;且设置了属性name的值;
程序本身不去创建对象,作为了被动的接收对象.
此过程就是控制反转;IOC; 由Spring 创建 管理 装配.
这里使用了set方法来进行注入的;若删除set方法;就无法得到属性name.
设置value是针对于基本数据;
设置实体类显示小叶子图标;
再看看刚才的UserDao,实际上,根据需要就可以直接在配置文件修改即可.
ref: 会引用 在Spring中设置创建的对象
3.1 IOC创建对象的方式
刚在在测执行时;注意到,输出有调用到无参构造方法;
那么如果将User类的无参构造方法去掉;即为User类写个显示的有参构造,默认隐式的无参构造就没有了;
再次执行,出现异常提示;提示初始化异常;
在xml配置文件中也有提示
IOC创建对象时默认使用无参构造方法,
那么如果说想用有参构造方法呢,有三种方式;
方式1:使用index(下标)
指定有参构造方法的参数是第几个; value
为参数赋值 ;
在beans.xml
文件的bean
标签下的constructor-arg
标签中配置
<?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-3.0.xsd">
<!--方式1:使用 index(下标) 指定有参构造方法的参数是第几个; value 为参数赋值 -->
<bean id="user" class="com.lzq.pojo.User">
<constructor-arg index="0" value="小智从零开始学Java"/>
</bean>
</beans>
执行,是调用了有参构造方法的;且为参数name赋值也取到了.
方式2:使用type 属性
显式的指定构造函数参数的类型;value
为参数赋值.
注意:
基本类型可直接写;引用类型要注明类的地址;
例如官方文档中是这么写的.
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="2001"/>
<constructor-arg type="java.lang.String" value="Zara"/>
</bean>
ok,用方式2调有参构造方法,为user类创建对象.
<?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-3.0.xsd">
<!--方式2: 使用 type属性 显式的指定构造函数参数的类型; value 为参数赋值-->
<bean id="user" class="com.lzq.pojo.User">
<constructor-arg type="java.lang.String" value="方式二"/>
</bean>
</beans>
执行,使用成功;
方式 3: 直接使用 参数名name
设置 ; value
参数赋值
<?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-3.0.xsd">
<!--方式3: 使用参数名name; -->
<bean id="user" class="com.lzq.pojo.User" >
<constructor-arg name="name" value="方式3"/>
</bean>
</beans>
执行,使用成功;
还有就是,在pojo包下,再创建一个Student类;
public class Student {
private int age;
public Student() {
System.out.println("Student类的无参构造方法");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
注意;仅仅是在beans.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-3.0.xsd">
<!--User类-->
<!--方式3: 使用参数名name; -->
<bean id="user" class="com.lzq.pojo.User" >
<constructor-arg name="name" value="方式3"/>
</bean>
<!--Student类-->
<bean id="student" class="com.lzq.pojo.Student">
</bean>
</beans>
诶,这里还是执行之前测试User类的代码;
public class Test01 {
public static void main(String[] args) {
//获取Spring得上下文对象;
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//由于创建对象就是 Spring 中的bean; 获取bean即可获取对象;
User user = (User) context.getBean("user");
System.out.println(user.toString());
}
}
但是输出结果时,发现Student类创建对象时调用的无参构造方法也有记录;
实际上, Spring容器就像是一个婚介网站
在配置文件加载的时候,容器中管理的对象就已经初始化了.
3.2 Spring配置说明
别名
alias
比如说;为User
类创建对象时的变量id user
取个别名u
<alias name="user" alias="u"/>
那么,在执行测试时,使用别名也能获取到这个User类的对象;
Bean的配置
细细看看<bean>标签内的
几个配置标签
id
就是 bean的唯一标识符
,也就相当于对象名
;
class
即 bean 对应的全限定名==> 包名 +类型
;
name
即 别名
;且 可以写多个别名,用逗号或者分号隔开
即可
<bean id="user" class="com.lzq.pojo.User" name="u1,u2;u3">
</bean>
import标签
一般在团队开发中使用;可以将多个配置文件导入合并为一个
<import resource="beans.xml"/>
<import resource="otherbeans.xml"/>
<import resource="otherbeans2.xml"/>
3.3 DI (依赖注入)
第一个就是构造函数注入,也就是刚才在创建对象时修改调用有参无参构造方法时;就使用过了.
第二个就是set注入,这个很重要
依赖: = = > bean对象的创建依赖于Spring容器
注入: = => bean对象中的所有属性,由容器注入.
3.3.1 set
以上是关于狂神说Java --- 记录Spring学习笔记的主要内容,如果未能解决你的问题,请参考以下文章