Spring学习笔记

Spring学习笔记

Spring的概述

Bean的两种创建规则

  • BeanFactory:

    ​ 提供的是一种延迟加载思想来创建bean对象。bean对象什么时候用什么时候创建。

    Resource reource = new ClassPathResource("bean.xml");

    Beanfactory factory = new XmlBeanfactory(resource);

  • ApplicationContext:

    ​ 提供的是一种立即加载思想来创建bean对象。只要解析完配置文件,就立马创建bean对象。

    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

Bean的三种实例化方法

  • 第一种方式:调用默认无参的构造函数——————此方法用的最多。

    ​ 默认情况下,如果类中没用默认无参构造函数,则创建失败,会报异常。

  • 第二种方式:使用静态工厂的方法创建对象。

    <bean id="staticCustomerService" class="包名.StaticFactory" factory-method="getCustomerService"></bean>

    ​ 需要使用bean标签的factory-method属性,指定静态工厂中创建对象的方法。

    第三种方式:使用实例工厂的方法创建。

    <bean id="instanFactory" class="包名.IntanceFactory"></bean>

    <bean id="instanCustomerService" factory-bean="instanceFactory" factory-method="getCustomerService"></bean>

Bean的作用范围

它是通过配置的方式来调整作用范围。

配置的属性:bean标签的scope属性。

属性的取值:

  • -PL;,. qsingleton:单例(默认值)
  • prototype:多例(当我们让spring接管struts2的action创建时,action必须配置此值)
  • request:作用范围时一次请求,和当前请求的转发。
  • session:作用范围是一次会话。
  • globalsession:作用范围是一次全局会话。

Spring的依赖注入

注入方式有三种

  • 构造函数注入

    直接在业务层写一个构造函数。

    public 函数名 (String driver,Integer port,Date today){this.driver = driver;this.port = port;this.today = today;}

    涉及的标签:

    constructor-arg

    标签的属性:

    ​ type:指定参数的类型。

    ​ index:指定参数的索引位置,从0开始。

    ​ name:指定参数的名称。


    上面三个属性是指定给那个参数赋值的,下面两个属性是指定赋什么值


    ​ value:指定基本数据类型或String类型的数据。

    ​ ref:指定其他bean类型数据。

    ​ 标签出现的位置:

    ​ 写在bean标签内部

    <bean id="custormerService" class="包名.CustormerServiceImpl">

    <constructor-arg name="driver" value="com.mysql.jdbc.Driver"></constructor-arg>

    <constructor-arg name="port" value="3306"></constructor-arg>

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

    </bean>

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

  • 使用set方法注入

    业务层直接添加参数drive、port、today的get和set方法。

    涉及的标签:

    property

    标签的属性:

    ​ name:指定参数的set方法名称。


    上面属性是指定给那个参数赋值的,下面属性是指定赋什么值


    ​ value:指定基本数据类型或String类型的数据。

    ​ ref:指定其他bean类型数据。

    标签出现的位置:

    ​ 写在bean标签内部

    <bean id="custormerService" class="包名.CustormerServiceImpl">

    <property name="driver" value="com.mysql.jdbc.Driver"></property>

    <property name="port" value="3306"></property>

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

    </bean>

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

    会有空指针异常,需要在XML里面配置bean,来创建对象

  • 使用注解注入

注入的数据类型有三种

  • 基本类型和string类型

  • 其他bean类型(必须是在spring的配置文件中出现过的bean)

  • 复杂类型(集合类型)

    同类型的标签可以互换

基于注解的IOC(用注解的方式替代XML中部分Bean的配置依赖注入)

Bean对象的创建

@Component

@Component("bean的id")

​ 作用:相当于配置了一个bean标签。

​ 位置:类上面。

​ 属性:value,含义是bean的id。

​ 默认值是当前类的短名首字母改小写。

由此注解衍生的三个注解:

@Controller

​ 一般用于表现的注解。

@Service

@Service("bean的id")

​ 一般用于业务层。

@Repository

​ 一般用于持久层。

用于注入数据

@Autowired

​ 作用:自动按照类型注入。

​ 只要有唯一的类型匹配就能注入成功。

​ 如果注入的bean在容器中类型不唯一时,它会把变量名作为bean的id,在容器中查找,找到后也能注入成功。

​ 如果没有找到一致的bean的id,则报错。

​ 当我们使用注解注入时,set方法就不是必须的。

@Qualifier

​ 作用:在自动按照类型注入的基础之上,再按照bean的id注入。

​ 它在给类成员注入数据时,不能独立使用,但是在给方法的形参注入数据时,可以独立使用。

​ 属性:value,用于指定bean的id。

@Resource

@Resource(name="bean的id")

​ 作用:直接按照bean的id注入。

​ 属性:name,用于指定bean的id。

以上三个注解都是用于注入其他bean类型的,用于注入基本类型和string类型需要使用Value

@Value

@Value("注入的数据")

​ 作用:用于注入基本类型和String类型数据。

​ 它可以借助spring的el表达式读取properties文件中的配置。

​ 属性:value,用于指定要注入的数据。

用于改变作用范围的

@scope

​ 作用:用于改变bean的作用范围。

​ 属性:value,用于指定范围的取值。

​ 取值和xml中scope属性的取值一样的。singleton prototype request session globalsession。

Spring的新注解

Bean

@Bean

@Bean(name="bean的id")

把方法的返回值存入容器中。用于替代XML中的关于数据库的配置,新建一个java文件的spring配置文件类,作用相当于bean.xml。

该注解有一个属性name用于指定bean的id,当不指定时它有默认值,默认值时方法的名称。



用下图的方法替代上图的XML配置



补充@Configuration标签,作用就是把当前类看成是spring的配置类

Import

@Import({类名.class})

作用是导入其他配置类

PropertySource

@PropertySource(value=

作用:导入其他配置文件,例如用于储存jdbc链接的属性数值文件等。

Qualifier

@Qualifier("bean的id")

作用:指定bean的id,用于解决bean的id与方法调用时参数名不一致的情况。

Spring整合junit

  • 第一步:拷贝spring提供的整合jar包

    ​ spring-test-4.2.4.RELEASE.jar

  • 第二步:使用junit提供的一个注解,把原有的main函数替换掉,换成spring提供的

    ​ @Runwith

    ​ 要换的类:SpringJunit4ClassRunner

  • 第三步:使用spring提供的注解告知spring,配置文件或者注解类所在的位置(注意区分是class还是location)

    ​ @ContextConfiguration

    如果是用纯注解的方式没有用XML配置文件@ContextConfiguration的参数就用class。


如果是用bean.xml配置文件就用location。

基于接口的动态代理

作用:在步改变代码的基础上,对已有的方法增强。(它是AOP思想的实现技术)

基于接口的动态代理:

​ 要求:被代理类最少实现一个接口

​ 提供者:JDK官方

​ 涉及的类:Proxy

​ 创建对象的方法:newProxyInstance(ClassLoader,Class[],InvocationHandler)

​ 参数的含义:

​ ClassLoader:类加载器,和被代理对象使用相同的的类加载器,一般都是固定写法。

​ Class[]:字节码数组,被代理类实现的接口。(要求代理对象和被代理对象具有相同的行 为)一般都是固定写法。

​ InvocationHandler:它是一个接口,就是用于我们提供增强代码的,一般都是写一个该接 口的实现类,实现类可以是匿名内部类。

​ 含义:如何代理,此处的代码只能是谁用谁提供。

​ 策略模式:

​ 使用要求:数据已经有了

​ 目的明确

​ 达成目标的过程就是策略


执行被代理对象的任何方法都会经过该方法,该方法有拦截的功能

方法参数:

​ Object proxy:代理对象的引用。不一定每次都会有。

​ Method method:当前执行的方法。

​ Object[] args:当前执行方法所需的参数

返回值:当前执行方法的返回值。


基于子类的动态代理

要求:被代理类不能是最终类。不能被final修饰

提供者:第三方CGLib

涉及的类:Enbancer

创建代理对象的方法:create(Class,Callback);

参数含义:

​ Class:被代理对象的字节码

​ Callback:如何代理。它和invocationHandler的作用一样的。它也是一个接口,我们一般使用该接口的子接口MethodInterceptor,在使用时我们也是创建该接口的匿名内部类。

执行被代理对象的任何方法,都会经过该方法。它和基于接口动态代理的invoke方法作用是一模一样的。

方法的参数:

​ 前面三个和invoke方法的参数含义和作用都一样。

​ MethodProxy methodProxy:当前执行方法的代理对象。一般不用


动态代理

回顾

功能:不改变源码的基础上对已有方法增强。

特点:字节码随用随创建,随用随加载。装饰着模式就是动态代理的一种体现。他与静态代理的区别就是静态代理是字节码一上来就创建好了,并完成加载。

动态代理常用的有两种方式

  • 基于接口的动态代理

    提供者:JDK官方的Proxy类。

    要求:被代理类最少实现一个接口。

  • 基于子类的动态代理

    提供者:第三方的CGLib,如果报asmxxxx异常,需要导入asm.jar。

    要求:被代理类不能用final修饰的类(最终类)。

Spring的AOP

AOP:面向切面编程。

​ 简单的说就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不改变源码的基础上,对我们已有的方法进行增强。

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

优势:减少重复代码、提高开发效率。

基于XML的AOP配置

  • 第一步把通知类交给Spring来管理。

  • 第二步导入aop名称空间,并且使用aop:config开始配置。

  • 第三步使用aop:aspect配置切面。id属性:用于给切面提供一个唯一标识。ref属性:用于应用通知Bean的id。

  • 第四步配置通知的类型,指定增强的方法何时执行。method属性:用于指定增强的方法名称 。pointcut属性:用于指定切入点表达式。

    切入点表达式:

    ​ 关键字:excution(表达式)

    ​ 表达式的写法:访问修饰符 返回值 包名.包名...类名.方法名(参数列表)

spring中的切入点表达式

  • 全匹配方式:

访问修饰符可以省略

返回值可以使用通配符,表示任意值返回值,通配符是*

包名可以使用通配符,表示任意包。但是,有几个包就需要写几个*


包名可以使用..表示当前包及其下所有子包

类名和方法名都可以使用通配符

参数列表可以使用具体类型,来表示参数类型

​ 基本类型直接写类型名称

​ 引用类型必须是包名.类名

参数列表可以使用通配符,表示任意参数类型,但是必须有参数

参数列表可以使用..表示有无参数均可,有参数可以是任意类型

  • 全通配方式:

实际开发中,我们一般情况下,都是对业务层方法进行增强

Spring中配置通用的切入点表达式

  • 定义通用的切入点表达式,如果写在了aop:aspect标签内部

  • 定义通用的切入点表达式,如果写在了aop:aspect标签外部(必须写在aop:aspect标签之前)

Spring中常用的四种通知类型

  • 配置前置通知:永远在切入点方法执行之前执行

  • 配置后置通知:切入点方法正常执行之后执行

  • 配置异常通知:切入点方法执行产生之后执行,他和后置通知永远只能执行一个

  • 配置最终通知:无论切入点方法是否正常执行,它都会在其后面执行

Spring中的环绕通知

环绕通知是Spring框架为我们提供的一种可以在代码中手动控制通知方法什么时候执行的方式。

问题

​ 当我们配置了环绕通知之后,切入点方法没有执行,而环绕通知里面的代码执行了。

分析

​ 由动态代理可知,环绕通知指的是invoke方法,并且里面由明确的切入点方法调用。而我们现在的环绕通知没有明确切入点方法调用

解决

​ Spring为我们提供了一个接口:ProceedingJionPoint。该接口可以作为环绕通知的方法参数来说明。

​ 在程序运行时,Spring框架会为我们提供该接口的实现类,供我们使用。

​ 该接口中有一个方法,proceed(),它的作用就等同于method.invoke方法,就是明确调用业务层核心方法(切入点方法)

Spring中的注解AOP配置

和IOC的注解配置方法基本相似

注解通知尽量使用环绕

不使用XML的AOP配置

  • 创建一个config的java类
  • 在java文件里面用注解替代XML文件里面的配置
  • 修改new一个对象的方法

jdbcTemplate的基本用法

jdbcTemplate的入门


jdbcTemplate的CRUD操作

jdbcTemplate在dao中的使用方式1

jdbcTemplate在dao中的使用方式1适合用注解方式配置


jdbcTemplate在dao中的使用方式2

jdbcTemplate在dao中的使用方式2适合用xml配置,因为他继承的Spring工具类不能用注解

抽取重复代码放到一个java文件中

还可以直接继承Spring里面的一个工具类

Spring中使用其他数据源

Spring的事务控制------准备环境

)

Spring基于XML的声明式事务配置



Spring基于纯注解的声明式事务配置




posted @ 2021-10-26 11:11  BreakRabbit  阅读(62)  评论(0)    收藏  举报