spring笔记

  1. IoC 的概念和作用

1.1程序的耦合和解耦

  1. 什么是程序的耦合

是对模块间关联程度的度量。模块间联系越多,其耦合性越强.

  1. 什么是内聚

内聚标志一个模块内各个元素彼此结合的紧密程度,一个好的内聚模块应当恰好做一件事。

  1. 解耦

我们在开发中,有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。

1.2 控制反转

1.什么是控制反转IOC?

把创建对象的权利交给框架。它包括依赖注入DI和依赖查找DL。意思就是之前我们需要对象的时候,自己new。现在我们把对象的创建权,交给spring工厂,我们需要对象的时候,从工厂中去拿。

作用:削减计算机程序的耦合(解除我们代码中的依赖关系)

 

  1. 使用 spring 的 IOC 解决程序耦合

2.1 spring基于xml的配置

2.1.1spring 中工厂的类结构图

2.1.1.1 BeanFactory 和 ApplicationContext 的区别

BeanFactory 才是 Spring 容器中的顶层接口。

ApplicationContext 是它的子接口。

BeanFactory 和 ApplicationContext 的区别:

创建对象的时间点不一样。

ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。

BeanFactory:什么使用什么时候创建对象。

2.1.1.2 ApplicationContext 接口的实现类

ClassPathXmlApplicationContext:

它是从类的根路径下加载配置文件 推荐使用这种

FileSystemXmlApplicationContext:

它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

AnnotationConfigApplicationContext:

当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

2.1.2 IOC 中 bean 标签和管理对象细节

2.1.2.1 bean 标签(把对象交给spring容器管理)

作用:

用于配置对象让 spring 来创建的。并且存入 ioc 容器之中

默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

属性:

id:给对象在容器中提供一个唯一标识。用于获取对象。

class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。

scope:指定对象的作用范围。

* singleton :默认值,单例的.

* prototype :多例的.

2.1.2.2 bean 的作用范围和生命周期

单例对象:scope="singleton"

一个应用只有一个对象的实例。它的作用范围就是整个引用。

生命周期:

对象出生:当应用加载,创建容器时,对象就被创建了。

对象活着:只要容器在,对象一直活着。

对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

多例对象:scope="prototype"

每次访问对象时,都会重新创建对象实例。

生命周期:

对象出生:当使用对象时,创建新的对象实例。

对象活着:只要对象在使用中,就一直活着。

对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

2.1.2.3 实例化 Bean 的三种方式

第一种方式:使用默认无参构造函数

<!--在默认情况下:

它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。-->

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>

2.1.3 spring 的依赖注入

2.1.3.1 依赖注入的概念

依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。

我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。

ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。

那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。

简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

2.1.3.2 构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置

的方式,让 spring 框架来为我们注入。具体代码如下:

/**

*/

public class AccountServiceImpl implements IAccountService {

private String name;

private Integer age;

private Date birthday;

public AccountServiceImpl(String name, Integer age, Date birthday) {

this.name = name;

this.age = age;

this.birthday = birthday;

}

@Override

public void saveAccount() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 使用构造函数的方式,给 service 中的属性传值

要求:

类中需要提供一个对应参数列表的构造函数。

涉及的标签:

constructor-arg

属性:

index:指定参数在构造函数参数列表的索引位置

type:指定参数在构造函数中的数据类型

name:指定参数在构造函数中的名称 用这个找给谁赋值

=======上面三个都是找给谁赋值,下面两个指的是赋什么值的

value:它能赋的值是基本数据类型和 String 类型

ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">

<constructor-arg name="name" value="张三"></constructor-arg>

<constructor-arg name="age" value="18"></constructor-arg>

<constructor-arg name="birthday" ref="now"></constructor-arg>

</bean>

<bean id="now" class="java.util.Date"></bean>

2.1.3.3 set 方法注入

顾名思义,就是在类中提供需要注入成员的 set 方法。具体代码如下:

/** */

public class AccountServiceImpl implements IAccountService {

private String name;

private Integer age;

private Date birthday;

public void setName(String name) {

this.name = name;

}

public void setAge(Integer age) {

this.age = age;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

@Override

public void saveAccount() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式

涉及的标签:

property属性:

name:找的是类中 set 方法后面的部分

ref:给属性赋值是其他 bean 类型的

value:给属性赋值是基本数据类型和 string 类型的

实际开发中,此种方式用的较多。

-->

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">

<property name="name" value="test"></property>

<property name="age" value="21"></property>

<property name="birthday" ref="now"></property>

</bean>

<bean id="now" class="java.util.Date"></bean>

2.2 spring基于基于注解的IOC 配置

2.2.1明确:写在最前

注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。

关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌握

Spring常用注解开发原则 自己写的类用注解,框架的类用配置文件。

<!-- 告知 spring 创建容器时要扫描的包 -->

<context:component-scan base-package="com.itheima"></context:component-scan>

2.2.2常用注解

2.2.2.1用于创建对象的相当于:<bean id="" class="">

在需要创建对象的类上加上对应IOC注解

@Component组件注解,该注解放在哪个类上,就表示把哪个类交给spring容器管理,value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。

下面三个注解都是组件注解的延伸注解,是spring对三层开发中每一层对象注解的一个规范。

@Controller 使用于web层

@Service使用于service层

@Repository使用于dao层

2.2.2.2用于注入数据的相当于:<property name="" ref=""> <property name="" value="">

ioc注解的属性对象必须存在于spring的容器中

@Autowired:自动按照类型注入。默认会去spring容器中按照类型寻找所需要注入的对象,如果找到一个唯一类型,就注入成功。如果找到不是唯一类型,

使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错.

如果该注解里面配置上了required=false,那么在找不到类型也找不到名字的时候,会返回null值,不会报错。但是如果不配置,就报错。

@Resource:该注解是直接按照名称注入。名称找不到再按照类型注入。如果都找不到,就报错。属性:name:指定 bean 的 id。

@Value:注入基本数据类型和 String 类型数据的.属性:value:用于指定值

2.2.2.3用于改变作用范围的:相当于:<bean id="" class="" scope="">

 @Scope注解:改变对象作用域的,属性:value:指定范围的值。取值:singleton prototype

单例对象生命周期:容器创建,对象创建,容器在,对象在,容器销毁,对象也销毁。

多例对象生命周期:真正使用的时候,对象创建,一直存在,由java垃圾回收器回收。

2.2.3 Spring 整合 Junit

(1)@RunWith 注解替换原有运行器

@RunWith(SpringJUnit4ClassRunner.class)

(2)使用@ContextConfiguration 指定 spring 配置文件的位置

@ContextConfiguration(locations= {"classpath:bean.xml"})

@ContextConfiguration 注解:

locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明

classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。

  1. AOP

3.1 AOP的相关概念

3.1.1 什么是AOP

Aop就是面向切面编程。我们可以在不修改源码的基础之上,对一个层面的代码进行增强。AOP编程是一个思想,spring的aop底层是使用了jdk动态代理或cglib动态代理实现的。

【动态代理学会一种,另一种也就会了,只是换了下类而已】

我理AOP就是假设A有三个方法,a,b,c

现在要对A进行增强,就是给他增加新的方法,不在A的代码中添加,而是新建一个动态代理类,在他里边给A加一个新的方法d

3.1.2 AOP 的作用及优势

作用:

在程序运行期间,不修改源码对已有方法进行增强。

优势:

减少重复代码

提高开发效率

维护方便

3.1.3 AOP 的实现方式

使用动态代理技术

3.2动态代理

3.2.1 Jdk动态代理

Jdk动态代理必须是对接口或者是接口的实现类。

 

创建一个java工程,确保有jdk的包。

编写一个需要被增强的类,该类实现了一个接口

创建一个工厂,生产代理对象

工厂中必须提供一个需要被增强的对象的实例或者接口本身

获取代理对象的方法

3.2.2 Cglib动态代理

Cglib是对类的增强的。

导入cglib的jar包

直接导入spring核心包,里面整合了有cglib的包。

编写一个需要被增强的类,该类暂时不实现接口

编写一个工厂,来生成代理对象

必须提供一个被代理对象的实例

提供一个生成代理对象的方法

测试类

3.2 spring中的aop

3.2.1Spring的AOP开发步骤

我们学习 spring 的 aop,就是通过配置的方式,实现上一章节的功能。

3.2.2 AOP相关术语

Pointcut连接点:被增强类中所有的方法都是连接点。

Joinpoint切入点:被增强的方法是切入点

Advice(通知/增强):就是增强类

Target(目标对象):被代理对象

Proxy(代理):最终代理对

Aspect(切面):切面就是通知和切入点的组合。

Weaving(织入):把增强类中的方法增强到目标的过程。

可见,所谓面向切面编程,说白了,就是要编写一通知,把通知中的方法织入到切入点上。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值