0%

Java|Spring学习

image-20210904133451706

1.初识Spring

Spring简介

Spring是针对企业级开发的框架,是技术使用更将方便,整合了现有的技术框架

  • SSH:Struct2 + Spring + Hibernate
  • SSM:SpringMCV + Spring + Mybatis

Spring优点

  • 轻量级,非入侵式
  • 开源的免费框架
  • 控制反转(IOC),面向切面(AOP)编程
  • 支持事物处理,对框架整合的支持

Spring组成

image-20210604151457606

扩展

image-20210604151952837

Spring Boot

  • 一个快速开发的脚手架
  • 基于SpringBoot可以快速的开发单个微服务。
  • 约定大于配置

Spring Cloud

  • SpringCloud是基于SpringBoot实现的

2.IOC理论推导

经典Java应用分层

image-20210604153048214

控制反转的思想

程序不在主动创建对象,而是被动的接受对象(控制权从程序转移到用户)。反转了,我们不负责创建对象,我们只被动处理对象

反转前:用户只能使用我们准备好的对象,有其他需求我们要额外新增修改

image-20210604154725356

反转后:用户可以任意创建对象,我们只负责去处理这些类

image-20210604154631248

IOC本质

image-20210604155144289

IOC就是为了解耦,让各个对象的依赖关系减弱

控制反转是一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式。在Spring中,实现控制反转的loC容器,其实现方法就是依赖注入(DI)

3.Spring初体验

xml法

  • 配置元数据:使用Spring创建对象,在Spring中称为bean
  • bean相当于new了一个对象
  • 获取spring的上下文对象,从xml提取出对象
  • IOC变成实现:由主动编程变为被动接收
  • 所谓IOC就是对象由Spring来创建,管理,装配

IOC创建对象的方式

  • 无参构造(默认方法)
  • 有参构造:
    • 下标赋值
    • 类型赋值(不建议使用)
    • 参数名赋值
  • 在配置XML文件加载的时候,容器中管理的对象就已经初始化了,即使在没有getbean这个对象,但是其已经在Spring容器中创建

4.Spring配置

别名

​ 除了对象名,我们也可以起小名来找到这个对象

Bean的配置

  • id:bean的唯一标识符,也就是相当于我们学的对象名
  • class:bean对象所对应的全限定名:包名+类名
  • name:也是别名,而且name可以同时取多个别名

import

​ 用于不同人开发的bean.xml文件合并在一起

Bean与Spring容器的关系

image-20210604163430319

5.依赖注入

构造器注入

当实体对象有有参构造方法的时候,需要使用构造器注入construct-args

Set方式注入

  • 依赖:bean对象的创建依赖于容器

  • 注入:bean对象中的所有属性,由容器来注入

  • 普通型注入:

1
2
<!--第一种:普通值注入,value        -->
<property name="name" value="黑心白莲"/>
  • Bean注入(注入另一对象实体,其也需要在bean中注册)
1
2
<!--第二种:-->
<property name="address" ref="address"/>
  • 数组型注入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!--数组        -->
    <property name="books">
    <array>
    <value>红楼梦</value>
    <value>西游记</value>
    <value>水浒传</value>
    <value>三国演义</value>
    </array>
    </property>
  • List型注入:

    1
    2
    3
    4
    5
    6
    7
    8
    <!--List        -->
    <property name="hobbies">
    <list>
    <value>打篮球</value>
    <value>看电影</value>
    <value>敲代码</value>
    </list>
    </property>
  • Map型注入:

    1
    2
    3
    4
    5
    6
    <property name="card">
    <map>
    <entry key="身份证" value="123456789987456321"/>
    <entry key="银行卡" value="359419496419481649"/>
    </map>
    </property>
  • Set型注入

1
2
3
4
5
6
7
8
<!--Set        -->
<property name="games">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
  • NULL型注入
1
2
3
4
<!--NULL        -->
<property name="wife">
<null/>
</property>
  • Properties型注入
1
2
3
4
5
6
7
8
9
<!--Properties        -->
<property name="info">
<props>
<prop key="driver">20191029</prop>
<prop key="url">102.0913.524.4585</prop>
<prop key="user">黑心白莲</prop>
<prop key="password">123456</prop>
</props>
</property>

其他注入方式

可以使用p命名空间和c命名空间进行注入

1
2
3
4
5
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.kuang.pojo.User" p:name="黑心白莲" p:age="20"/>

<!--c命名空间注入,通过构造器注入:constructor-args-->
<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22"/>

6.Bean解析

Bean的作用域

image-20210605114941989

Spring默认使用单例模式(singleton)

Bean的自动装配

  • 手动装配:每一个属性都要自己去设置
  • 自动装配是Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性()

自动装配类型:

image-20210605115608244

  • byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id;
  • byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean;

7.使用注解开发

注解配置

  • 导入约束
  • 配置注解的支持: <context:annotation-config/>

@Autowired注解

  • 可以在属性或者set方法上使用
  • 使用Autowired方法就可以不用编写set方法(但是需要使用自动装配,且符合命名ByName)

不使用注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class People {
private Cat cat;
private Dog dog;
private String name;

public Cat getCat() {
return cat;
}

public void setCat(Cat cat) {
this.cat = cat;
}

public Dog getDog() {
return dog;
}

public void setDog(Dog dog) {
this.dog = dog;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

使用注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class People {
//如果显式定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;

// set的方法都被省略掉了
public Cat getCat() {
return cat;
}

public Dog getDog() {
return dog;
}

}

@Qualifier注解

  • 如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class People {
    @Autowired
    @Qualifier(value = "cat111")
    private Cat cat;
    @Autowired
    @Qualifier(value = "dog222")
    private Dog dog;
    private String name;
    }

@Resource注解

@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired通过byType的方式实现,而且必须要求这个对象存
  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错
  • 执行顺序不同:@Autowired通过byType的方式实现。

使用注解开发

属性注入:

1
2
3
4
5
6
7
8
9
10
//等价于<bean id="user"class="com.kuang.pojo.User"/>
//@Component 组件

@Component
public class User {

//相当于 <property name="name" value="白莲"/>
@Value("白莲")
public String name;
}

衍生的注解:

@Component有几个衍生的注解,按照mvc三层架构分层

1
2
3
dao 【@Repository】
service 【@Service】
controller 【@Controller】

自动装配:

  • @Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value = “xxx”)去配置。
  • @Nullable 字段标记了了这个注解,说明这个字段可以为null;
  • @Resource:自动装配通过名字,类型

注解与xml

  • xml更加万能,适用于任何场合,维护简单方便
  • 注解不是自己类使用不了,维护相对复杂
  • 最佳的实践是:注解只负责完成属性的注入,xml用来管理bean

8.Java配置Spring

完全抛弃xml配置,采用JavaConfig来配置Spring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 这个也会Spring容器托管,注册到容器中,因为它本来就是一个@Component
// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
@Configuration
@ComponentScan("com.autovy.pojo")
@Import(AutovyConfig2.class)
public class AutovyConfig {

// 注册一个bean,就相当于我们之前写的一个bean标签
// 这个方法的名字,就相当于bean标签中id属性
// 这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User user(){
return new user(); // 就是返回要注入到bean的对象!
}

9.代理模式

真实角色通过他们的替身——代理对象进行交流

image-20210605150430423

静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
  • 客户:访问代理对象的人!

实现过程:

  • 代理对象组合目标对象,并帮忙为目标对象实现接口的附加方法
  • 客户只需要访问代理对象即可

代理模式好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共角色就交给代理角色!实现了业务的分工
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低

动态代理

动态代理的代理类是自动生成的,可以分为:基于接口的动态代理(JDK动态代理),基于类的动态代理(cglib)两种

动态代理的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共角色就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

10.AOP详解

AOP实现机制

image-20210605153837739

AOP简介

  • AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

image-20210605153954045

AOP在Spring中

AOP在不改变原有代码的情况下,增加新的功能

有三种实现方法:

  • Spring的API接口实现
  • 自定义类来实现AOP
  • 使用注解实现