What Have Learn About Spring(Spring 学习理解的笔记)

What Have Learn About Spring

[Spring summary]

Spring 解决什么问题

  1. 类之间的依赖

不同类之间利用实例化对象传递功能方法,在每次创建对象时候,都会产生一段耦合代码。

  1. 控制事物繁琐

每次事物的控制都需要冗杂的try-catch代码块来,可以使用AOP(Aspect Oriented Programming)思想的具体实现来解决

  1. 框架的引入复杂

每个框架的单独引入比较乱,需要一个对其他框架的接入接口式的的管理。

  1. Spring 解决了什么

    1. Spring 能帮我们低侵入/低耦合地根据配置文件创建及组装对象之间的依赖关系。IoC

    2. Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制等。AOP

    3. Spring 能非常简单的且强大的声明式事务管理。AOP TX

    4. Spring 提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,且自己也提供了一套 JDBC 模板来方便数据库访问。

    5. Spring 提供与第三方 Web(如 Struts1/2、JSF)框架无缝集成,且自己也提供了一套 Spring MVC 框架,来方便 Web 层搭建。 SSM

    6. Spring 能方便的与如 Java Mail、任务调度、缓存框架等技术整合,降低开发难度。

Spring 有什么

Spring主要是一个容器,里面装了一些对象(比如SqlSessionFactory之类的可以被公用),然后大家可以随取随用。

SSM流程
Spring Framework Runtime

实现IOC思想来创建对象放在容器内,实现DI思想来建立对象之间的关系

IOC思想:Inversion Of Control,控制权的转移,把创建对象的权力转移给容器来控制

Spring容器通过配置文件配置的内容,利用反射操作创建出需要的对象,把这些对象放在Spring容器中,随时用。

    <!-- 第一步!配置文件中配置自己想要什么对象(Bean豆子) -->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="username" value="${jdbc.username}"/>
    </bean>
    <!-- 可以在编写的类上面加注解,Spring会自动扫描出来,初始化创建一个豆子 -->
    @Service
    public class AccountServiceImpl implements IAccountService {}
    <!-- 第二步!在代码中可以通过注解拿对象(豆子),也可以把Spring容器拿到手从里面取 -->
    public class UserController {
    	@Autowired
    	private IUserService userService;
    }

DI思想:Dependency Injection,依赖注入,把对象的关系连接起来!

举例:容器帮我们创建A对象和B对象,我们想把B对象设置为A对象的一个字段值,A和B就有一个赋值的依赖关系,DI思想就是要连接起来对象的这种关系。Spring容器就通过取值与赋值把对象连接起来

简单的豆子关系

    <!-- 第一种!配置文件中往豆子里注入值 -->
	<!-- dataSource豆子 -->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="username" value="${jdbc.username}"/>
    </bean>
	<!-- 事务管理器豆子,把dataSource豆子拿过来做属性值-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
		<!-- 注入!-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 第二种!通过注解,从容器中拿取豆子,同上 -->
    public class UserController {
    	@Autowired
    	private IUserService userService;
    }

实现AOP思想来解决事物等繁琐代码

AOP(Aspect Oriented Progranmming)

AOP是面向切面编程,把操作分层,分清主次等层次。

	//有事务管理的数据库操作可以分为四层
	try {
		//1: start transaction
		transactionManager.startTransaction();
		//2: do the main job
		userService.addAUser(user);
		//3: commit transaction
		transactionManager.commitTransaction();
	} catch (Exception e) {
		//4: rollback the transaction
		transactionManager.rollbackTransaction();
	}

通过把操作分层,我们可以筛选出我们感兴趣的主操作(第二步)和事物等其他的为主操作服务的操作。可以利用AOP思想,把操作分层,然后为主操作类(Service类)来创建代理类来减少主操作种的代码量,专心写主操作中的代码

AOP理解
自我理解:AOP的切面可以被理解为一层操作,每次请求/操作都可以被分成多层切面。

静态代理和动态代理来实现AOP思想

  1. 静态代理

自我理解:为需要添加其他操作的Service方法(主操作)编写一个代理类方法,代理方法就像汉堡,把精华部分(主操作)和为精华服务的部分(事物管理、日志记录等)分层起来。

静态代理示意图

  1. 动态代理

    1. The same as 静态代理
      每一个需要代理的Service类生成一个代理,代理的内容就是添加为主操作其他的操作。

    2. The differences from 静态代理

      自动生成的,要接受主顾的接口信息,看看需要代理哪些方法。

      自动生成的,为每一个主顾生成的代理(生产的汉堡包)除了主操作都一样

      不确定谁要代理,在 运行时候生成代理

自我理解:有太多需要代理的主操作了,他们需要的代理都是简单的添加事物操作,那么我就可以重构了,接收类的接口信息,为它的每一个方法添加事物操作,组成一个代理类来用。

动态代理示意图

上面只是理解,静态代理是自己写的,动态代理需要实现InvocationHandler写一个代理类的模板类,利用Proxy类拿取动态代理类。静态代理是一个手工汉堡包,可以吃的那种。动态代理类通过看源码我理解为是一个空壳子,所有人得到的只是一套餐具,吃的是同一个汉堡包(代理类的模板类的invoke方法)。

Spring 操作AOP

Spring中的AOP实现单位为方法,每个需要加工成汉堡包的肉片(方法)被称为joinPoint,所有待加工成汉堡包的肉片(方法)组成pointCut。需要的菜叶和面包片(事物、日志等对主操作的增强)成为advice,pointCut和advice组装成多个汉堡包,汉堡包叫aspect(切面)。(我觉得joinPoin和advicet才应该叫切面,可不知为什么汉堡包才叫切面。

AOP切面可以在Spring容器的配置文件中配置,也可以通过注解定义一个切面类

		<!-- AOP配置 -->
		<aop:config>
			<!-- 插入管理事务的joinPoint -->
			<aop:aspect ref="myTransactionManager">
				<aop:pointcut
					expression="execution(* com.gasin.spring.service.impl.*ServiceImpl.addAUser(..))"
					id="transactionPointcut" />
				<aop:around method="arountTransaction" pointcut-ref="transactionPointcut"/>
				<!-- <aop:before method="startTransaction" pointcut-ref="transactionPointcut" />
				<aop:after-returning method="commitTransaction" pointcut-ref="transactionPointcut"/>
				<aop:after-throwing method="rollbackTransaction" pointcut-ref="transactionPointcut"/> -->
			</aop:aspect>
			<!-- 插入记录ERROR的切面 -->
			<aop:aspect ref="errorLogUtil">
				<aop:pointcut expression="execution(* com.gasin.spring.service.impl.*ServiceImpl.updateAUser(..))" id="errorNotePointCut"/>
				<aop:after-throwing method="noteAError" pointcut-ref="errorNotePointCut" throwing="e"/>			
			</aop:aspect>
			<!-- 插入方法运行的切面 -->
			<aop:aspect ref="writeMethodLog">
				<aop:pointcut expression="execution(* com.gasin.spring.service.impl.*ServiceImpl.updateAUser(..))" id="errorNotePointCut"/>
				<aop:before method="writeMethodLog" pointcut-ref="errorNotePointCut" />
			</aop:aspect>
		</aop:config>

	<!-- spring配置文件中AOP注解解析器 -->
	<aop:aspectj-autoproxy/>
@Component
@Aspect
public class MyTransactionManager {
	/* 贴上的注解value为AspectJ语句*/
	@Pointcut("execution(* com.gasin.spring.service.impl.*ServiceImpl.addAUser(..))")
	public void transactionPointAsPect(){}
	/**
	 * Around方法
	 */
	@Around("transactionPointAsPect()")
	public void arountTransaction(ProceedingJoinPoint pjp) {
		try {
			startTransaction();
			pjp.proceed();
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
	/**
	 * 开启事物
	 */
	@Before("transactionPointAsPect()")
	public void startTransaction() {
	}
	/**
	 * 提交事物
	 */
	@After("transactionPointAsPect()")
	public void commitTransaction() {
	}
	@AfterReturning("transactionPointAsPect()")
	public void afterReturnTransaction() {
	}
	/**
	 * 回滚事物
	 */
	@AfterThrowing("transactionPointAsPect()")
	public void rollbackTransaction() {
	}
}

Spring 引入其他框架

我还不太了解这相关的知识,等着自己慢慢学。

over

by wangyk

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值