Spring学习笔记整理

Spring概述

Spring是当前最流行的Java EE企业级开发框架,它有以下优良特性:
①非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
②依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现
③面向切面编程:Aspect Oriented Programming——AOP
④容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
⑤组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在Spring中可以使用XML和Java注解组合这些对象
⑥一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方库(实际上Spring
自身也提供表述层的SpringMVC和持久层的Spring JDBC)

Spring的两大核心:IOC(控制反转)和AOP(面向切面编程)

IOC:Inversion of Control

概念:

把创建对象的权利交给框架,是框架的主要特征。它包含依赖注入DI(Dependency Injection)和依赖查找(Dependency Lookup)

作用:

减少类之间的依赖关系,降低程序的耦合度

Spring对bean的管理细节:

1、创建bean对象
id是唯一标识
class是类路径

<bean id="accountService" class="com.jxau.services.impl.AccountServiceImpl"></bean>

2、设置bean对象的作用范围
scope:指定bean的作用范围
scope的参数:
singleton:单例的(默认的)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session

<bean id="accountService" class="com.jxau.services.impl.AccountServiceImpl" scope="prototype"></bean>
Spring中的依赖注入:

当前类需要用到其他类的对象或数据时,由Spring为我们提供
可注入的数据:
1、基本数据类型和String
2、其他bean类型(在配置文件中配置过或注解过的类)
3、复杂类型/集合类型
注入的方式:
1、构造函数注入
优势:
在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功
弊端:
改变了bean对象的实例化方式,使我们在创建对象时,如果遇不到这些数据也必须提供
name:唯一标识
value:变量值(基本数据类型和String)
ref:变量值(其他bean类型)

<constructor-arg name="name" value="ding"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
<bean id="now" class="java.util.Date"></bean>

2、set方法注入(常用)
优势:
创建对象时没有明确的限制,可以直接使用默认构造函数
弊端:
如果某个成员必须有值,set方法可能没有调用

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

3、复杂类型的注入
用于给List集合注入的标签:
list、array、set
用于给Map集合注入的标签:
map、props
在这里插入图片描述

<bean id="accountService2" class="com.jxau.services.impl.AccountServiceImpl2">
        <property name="myStrs">
            <array>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </array>
        </property>
        <property name="mySet">
            <array>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </array>
        </property>
        <property name="myList">
            <array>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </array>
        </property>
        <property name="myMap">
            <map>
                <entry key="testA" value="aaa"></entry>
                <entry key="testB" value="bbb"></entry>
            </map>
        </property>
    </bean>
IOC基于注解的配置

使用注解配置时,要在配置文件中声明要扫描的包

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

用于创建对象的:
它们的作用就和在xml配置文件中编写一个bean标签实现的功能是一样的
@Component
作用:用于把当前类对象存入spring容器中
属性:value,用于指定bean的id,当我们不写时,它的默认值是当前类名,且首字母小写
@Controller:一般用在表现层
@Service:一般用在业务层
@Repository:一般用在持久层
以上三个注解的作用和属性与@Component是一模一样的
它们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰

用于注入数据的:
它们的作用就和在xml中配置文件中的bean标签中写一个property标签的作用是一样的
@AutoWired:
作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
细节:
在使用注解注入时,set方法就不是必须的了
@Qualifier:
作用:在按照类型(@Autowired)注入的基础上再按照名称注入,它在给类成员注入时不能单独使用,但是给方法参数注入时可以
属性:
value:用于指定注入bean的id
@Resource:
作用:直接按照bean的id注入,它可以单独使用
属性:
name:用于指定bean的id
以上三个注解都只能注入其他bean类型的数据,而基本数据类型和String类型无法注入
另外,集合类型的注入只能通过xml来实现
@value
作用:用来注入基本数据类型和String类型的数据
属性:
value:用于指定数据的值,它可以使用spring中SpEl(也就是spring的el表达式)
SpEL的写法:${表达式}

用于改变作用范围的
他们的作用就和在bean标签中使用scope属性实现的功能是一样的
@Scope
作用:用于指定bean的作用范围
属性:
value:指定范围的取值。常用取值:singleton、prototype

和生命周期相关的
他们的作用就和bean标签中使用init-method和destroy-method的作用是一样的
@PostDestroy
作用:初始化
@PostConstruct
作用:销毁

AOP:Aspect Oriented Programming

概念:

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

作用:

利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。

spring中AOP相关的专业术语

Joinpoint(连接点):
所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。
Pointcut(切入点):
所谓切入点是指我们要对哪些Joinpoint进行拦截的定义。
Advice(通知/增强):
所谓通知是指拦截到Joinpoint之后要做的事情
通知的类型:前置通知、后置通知、异常通知、最终通知、环绕通知
Introduction(引介):
引介是一种特殊的通知,在不修改代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field
Target(目标对象):
代理的目标对象
Weaving(织入):
是指把增强应用到目标对象来创建新的代理对象的过程
spring采用动态代理织入
Proxy(代理):
一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面):
切入点和通知(引介)的结合

spring中基于xml的AOP配置

1、使用aop:config标签表明开始AOP配置
2、使用aop:aspect标签表明配置切面
属性:
id:给切面提供一个唯一标识
ref:指定通知类bean的id
3、在aop:aspect标签内部使用对应标签来配置通知的类型
我们现在示例是让printLog方法在切入点方法执行前执行:所以是前置通知
aop:before:表示配置前置通知
method:用于指定Logger类中哪个方法是前置通知
pointcut:用于指定切入点表达式,该表达式的含义是指对业务层中哪些方法增强
切入点表达式的写法:
关键字:execution(表达式)
表达式:
访问修饰符 返回值 包名.包名.包名…类名.方法名(参数列表)
标准的表达式写法:

public void com.jxau.service.impl.AccountServiceImpl.saveAccount()

访问修饰符可省略:

void com.jxau.service.impl.AccountServiceImpl.saveAccount()

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

* com.jxau.service.impl.AccountServiceImpl.saveAccount()

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

* *.*.*.*.AccountServiceImpl.saveAccount()

包名可以使用…,表示当前包及其子包:

* *..AccountServiceImpl.saveAccount()

类名和方法名都可以使用*来实现通配:

* *..*.*()

参数列表:
可以直接写参数类型:
基本数据类型直接写名称

* *..*.*(int)

引用类型写包名.类名的方式

* *..*.*(java.lang.String)

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

* *..*.*(*)

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

* *..*.*(..)

全通配写法:

 * *..*.*(..)

实际开发中切入点表达式的通常写法:
切到业务层实现类下的所有方法

* com.jxau.service.impl.*.*(..)

4、配置AOP示例

<aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.jxau.service.impl.*.*(..))"/>
        <aop:aspect id="tsManager" ref="tranSactionManager">
            <aop:before method="beginTransaction" pointcut-ref="pt1"></aop:before>
            <aop:after-returning method="commit" pointcut-ref="pt1"></aop:after-returning>
            <aop:after-throwing method="rollback" pointcut-ref="pt1"></aop:after-throwing>
            <aop:after method="release" pointcut-ref="pt1"></aop:after>
        </aop:aspect>
    </aop:config>
spring中基于注解的AOP配置

在配置文件中开启spring对注解AOP的支持

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

1、配置切面

@Aspect

2、配置切入点表达式

@Pointcut("execution(* com.jxau.service.impl.*.*(..))")
    private void pt1(){}

3、配置通知
注意:使用注解配置时需要使用环绕通知,否则会造成执行顺序出错(最终通知在后置通知之前执行)

@Around("pt1()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        Object returnValue = null;
        try{
            //1、获取参数
            Object[] args=proceedingJoinPoint.getArgs();
            //2、开启事务
            this.beginTransaction();
            //3、执行方法
            returnValue=proceedingJoinPoint.proceed(args);
            this.commit();
            return returnValue;
        }catch (Throwable throwable){
            this.rollback();
            throw new RuntimeException();
        }finally {
            this.release();
        }
    }

Spring的声明式事务控制

基于xml

spring中基于xml的声明式事务控制配置步骤
1、配置事务管理器
2、配置事务通知
此时我们需要导入约束:tx名称空间和约束,也需要aop的
使用tx:advice标签配置事务通知
属性:
id:唯一标识
transaction-manager:给事务通知提供一个事务管理器引用
3、配置aop中的通用切入点表达式
4、建立切入点表达式和事务通知的对应关系
5、配置事物的属性

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<!--配置事务的属性
            isolation:指定事务的隔离级别,默认值是DEFAULT,表示使用数据库的隔离级别
            propagation:用于指定事务的传播行为,默认值是REQUIRED,表示一定存在事务,增删改的选择。查询方法可以选择SUPPORTS
            read-only:用于指定事务是否只读,只有查询方法才能设置为true,默认值是false,表示读写
            timeout:指定事务的超时时间,默认值是-1,表示永不超时。如果指定了值,以秒为单位
            rollback-for="":用于指定一个异常,当产生该异常时,事务回滚。产生其他异常时,事务不回滚。没有默认值,表示任何异常都回滚
            no-rollback-for="":用于指定一个异常,当产生该异常时,事务不回滚。产生其他异常时,事务回滚。没有默认值,表示任何异常都回滚
        -->
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--配置切入点表达式-->
        <aop:pointcut id="pt1" expression="execution(* com.jxau.service.impl.*.*(..))"/>
        <!--建立切入点表达式和事务通知的关系-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
    </aop:config>

基于注解

spring基于直接的声明式事务控制配置步骤
1、配置事务管理器
2、开启sprig对注解事务的支持
3、在需要事务支持的地方使用@Transactional注解

	<!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--开启spring对注解事务的支持-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

在这里插入图片描述

发布了3 篇原创文章 · 获赞 1 · 访问量 58

猜你喜欢

转载自blog.csdn.net/dlhlzxw/article/details/105127340