文章目录
- 1. 什么是Spring
- 2.Spring的优势
- 3.控制反转IOC
- 3.1 什么是控制反转
- 3.2依赖注入实现的三种方式
- 4.BeanFactory和ApplicationContext有什么区别?
- 4.1 **BeanFactory**
- 4.2 **ApplicationContext**
- 4.3 区别
- 5. Spring的三种配置方式
- 5.1 XML配置
- 5.2 注解配置
- 5.3 基于Java配置的方式配置Spring
- 6. Spring Bean的生命周期
- 7. Spring Bean的作用域
- 1. 动态代理
- 动态代理分为两大类
- 2. AOP
- 2.1 使用Spring实现Aop
- 方式一:使用Spring接口【主要是Spring Api接口实现】
- 方式二:自定义来实现Aop【主要是切面定义】
- 方式三:使用注解
1. 什么是Spring
Spring框架是一个轻量级开放源代码应用程序框架,以IOC(控制反转)和AOP(面向切面编程)为内核
2.Spring的优势
- 方便解耦,简化开发
- AOP编程的支持
- 声明式事务的支持
- 方便测试
- 方便集成各种优秀的框架,例如mybatis,Quartz等
- 降低JavaEE API的使用难度(可以使用各种模板,例如redis)
3.控制反转IOC
3.1 什么是控制反转
控制反转是一种思想,DI是实现IOC的一种方法,在没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建有程序开发人员控制。在控制反转后,将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了
3.2依赖注入实现的三种方式
- 构造器注入 (默认使用无参构造,如果不存在则可以使用以下方式)
<!-- 方式一: 使用索引-->
<bean id="user" class="com.study.bean.User">
<constructor-arg index="0" value="张三"/>
</bean>
<!-- 方式二: 通过类型创建 不建议使用-->
<bean id="user2" class="com.study.bean.User2">
<constructor-arg type="java.lang.String" value="李四"/>
</bean>
<!-- 方式三: 直接通过参数名 推荐使用-->
<bean id="user3" class="com.study.bean.User3">
<constructor-arg name="name" value="王五"/>
</bean>
- setter方法注入
- 接口注入
4.BeanFactory和ApplicationContext有什么区别?
4.1 BeanFactory
是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;
4.2 ApplicationContext
继承BeanFactory接口,ApplicationContext提供了更多的功能
- 继承了MessageSource,支持国际化
- 统一的资源文件访问方式
- 提供在监听器中注册bean的事件
- 同时加载多个配置文件
4.3 区别
BeanFactory: BeanFactory在启动的时候不会去实例化Bean,只有从容器中拿Bean(使用Bean)的时候才会去实例化;(适用于对资源要求高的应用)
**ApplicationContext: **ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化; (更适合于WEB应用)
两个接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tOXfWVv-1645431103864)(C:\Users\Kant\AppData\Roaming\Typora\typora-user-images\image-20220218171742010.png)]
- FileSystemXmlApplicationContext: 默认是去项目的路径下加载,可以是相对路径,也可以是绝对路径
- **ClassPathXmlApplicationContext: **默认会去 classPath 路径下找。classPath 路径指的就是编译后的 classes 目录
5. Spring的三种配置方式
5.1 XML配置
5.2 注解配置
使用注解配置需要在配置文件中添加以下配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解 -->
<context:annotation-config />
<!-- 配置包扫描 -->
<context:component-scan base-package="com.study"/>
</beans>
重要的几个注解
- **@Autowired:**默认byType对比,如果碰到多个同类型,则再根据byName对比,如果匹配到多个同名称,则抛出异常
@Qualifier(value = “xxx”):可以手动指定按byName方式注入,和@Autowired配合使用 - **@Resource:**默认按照byName注入,如果找不到则按照byType注入,如果还是找不到则抛出异常。无论是按照byName还是byType,只要匹配多个则抛出异常。注解有以下两种属性:
- type:@Resource(type=”bean的class”)
- name:@Resource(name=”bean名字”)
该注解是属于J2EE ,减少了与spring的耦合
- **@Component:**使用与类上用于实例化bean
- **@Service:**用于在service层实例化bean
- **@Reponsitory:**用于dao层实例化bean
- **@Scope:**标注bean的作用范围
5.3 基于Java配置的方式配置Spring
创建ApplicationConfig.java
package com.study.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
/**
* @PackgeName: com.study.config
* @ClassName: ApplicationConfig
* @Author: lixinkang
* Date: 2021/12/29 17:53
* project name: D03_Spring
* @Version:
* @Description:
*/
@Configuration
@ComponentScan("com.study")
public class ApplicationConfig {
}
实例化:使用AnnotationConfigApplicationContext类进行实例化
/*使用全注解*/
@Test
public void test3(){
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
AnnoService annoService = context.getBean(AnnoService.class);
annoService.save();
}
6. Spring Bean的生命周期
- 通过构造器或工厂方法创建Bean的实例
- 为Bean的属性设置值和其他对Bean的引用
- 将 Bean 实 例 传 递 给 Bean 后 置 处 理 器 的 postProcessBeforeInitialization 方法
- 调用 Bean 的初始化方法(init-method)
- 将 Bean 实 例 传 递 给 Bean 后 置 处 理 器 的 postProcessAfterInitialization 方法
- Bean 可以使用了
- 当容器关闭时, 调用 Bean 的销毁方法(destroy-method)
7. Spring Bean的作用域
singleton | 默认:单例模式 | 整个应用中只会创建一次 |
prototype | 原型 | 为每个Bean请求都会创建一次实例 |
request | 请求 | 在每个http请求中创建一个单例对象,请求完成后则会被垃圾回收器销毁 |
session | 会话 | 每个session中有一个bean的实例,在session过期后,bean会消失 |
global- session | 全局作用域 |
1. 动态代理
动态代理分为两大类
- 基于接口 — JDK 动态代理
- 基于类 cglib
- Java字节码 javasist
2. AOP
2.1 使用Spring实现Aop
【重点】 使用Aop织入,需要导入一个依赖包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
方式一:使用Spring接口【主要是Spring Api接口实现】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="com.study.service.UserServiceImpl"/>
<bean id="log" class="com.study.log.Log"/>
<bean id="afterLog" class="com.study.log.AfterLog"/>
<!--方法一:使用原生Spring API接口-->
<aop:config>
<!--切入点:expression:表达式(要执行的位置)-->
<aop:pointcut id="pointcut" expression="execution(* com.study.service.UserServiceImpl.*(..))"/>
<!--执行环绕-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut" />
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
方式二:自定义来实现Aop【主要是切面定义】
DiyPointCut.java
package com.study.diy;
/**
* @PackgeName: com.study.diy
* @ClassName: DiyPointCut
* @Author: lixinkang
* Date: 2021/12/28 14:19
* project name: D03_Spring
* @Version:
* @Description:
*/
public class DiyPointCut {
public void before(){
System.out.println("=============方法执行前===============");
}
public void after(){
System.out.println("=============方法执行后===============");
}
}
applicationContext.xml
<!--方法二:自定义 切面 实现-->
<bean id="diyPointCut" class="com.study.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref要引用的类-->
<aop:aspect ref="diyPointCut">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.study.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:after method="after" pointcut-ref="point"></aop:after>
<aop:before method="before" pointcut-ref="point"></aop:before>
</aop:aspect>
</aop:config>
方式三:使用注解
applicationContext.xml
<!--方式三 开启注解支持-->
<aop:aspectj-autoproxy/>
AnnPointCut.java
package com.study.diy;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @PackgeName: com.study.diy
* @ClassName: AnnPointCut
* @Author: lixinkang
* Date: 2021/12/28 15:21
* project name: D03_Spring
* @Version:
* @Description:
*/
// 标注这个类是一个切面
@Aspect
public class AnnPointCut {
@Before("execution(* com.study.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("========方法执行前==========");
}
}