文章目录

  • 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的优势

  1. 方便解耦,简化开发
  2. AOP编程的支持
  3. 声明式事务的支持
  4. 方便测试
  5. 方便集成各种优秀的框架,例如mybatis,Quartz等
  6. 降低JavaEE API的使用难度(可以使用各种模板,例如redis)

3.控制反转IOC

3.1 什么是控制反转

控制反转是一种思想,DI是实现IOC的一种方法,在没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建有程序开发人员控制。在控制反转后,将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了

3.2依赖注入实现的三种方式

  1. 构造器注入 (默认使用无参构造,如果不存在则可以使用以下方式)
<!-- 方式一: 使用索引-->
    <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>
  1. setter方法注入
  2. 接口注入

4.BeanFactory和ApplicationContext有什么区别?

4.1 BeanFactory

是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;

4.2 ApplicationContext

继承BeanFactory接口,ApplicationContext提供了更多的功能

  1. 继承了MessageSource,支持国际化
  2. 统一的资源文件访问方式
  3. 提供在监听器中注册bean的事件
  4. 同时加载多个配置文件

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)]

  1. FileSystemXmlApplicationContext: 默认是去项目的路径下加载,可以是相对路径,也可以是绝对路径
  2. **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>

重要的几个注解

  1. **@Autowired:**默认byType对比,如果碰到多个同类型,则再根据byName对比,如果匹配到多个同名称,则抛出异常
    @Qualifier(value = “xxx”):可以手动指定按byName方式注入,和@Autowired配合使用
  2. **@Resource:**默认按照byName注入,如果找不到则按照byType注入,如果还是找不到则抛出异常。无论是按照byName还是byType,只要匹配多个则抛出异常。注解有以下两种属性:
  1. type:@Resource(type=”bean的class”)
  2. name:@Resource(name=”bean名字”)

该注解是属于J2EE ,减少了与spring的耦合

  1. **@Component:**使用与类上用于实例化bean
  2. **@Service:**用于在service层实例化bean
  3. **@Reponsitory:**用于dao层实例化bean
  4. **@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的生命周期

  1. 通过构造器或工厂方法创建Bean的实例
  2. 为Bean的属性设置值和其他对Bean的引用
  3. 将 Bean 实 例 传 递 给 Bean 后 置 处 理 器 的 postProcessBeforeInitialization 方法
  4. 调用 Bean 的初始化方法(init-method)
  5. 将 Bean 实 例 传 递 给 Bean 后 置 处 理 器 的 postProcessAfterInitialization 方法
  6. Bean 可以使用了
  7. 当容器关闭时, 调用 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("========方法执行前==========");
    }
}