Spring 框架小结

Spring 框架小结

演变

在 Spring 框架出现之前,开发一个 EJB(Enterprise Java Bean)需要定义接口并进行大量配置,这些工作繁琐与枯燥超过了开发本身。另外,由 JSP(Java Server Page)生成的 Servlet 是运行在 Web 容器中的,而 EJB 则是运行在 EJB 容器中的,两个容器中服务间的调用又需要新的配置以及网络资源的消耗。

2004 年,Spring 1.0 版本发布,其使用控制反转(IoC,Inversion of Control)技术来管理资源,降低代码耦合度,并用面向切面编程(AOP,Aspect Oriented Programming)动态代理技术来抽离重复性的代码,使得开发人员能够专注于业务代码的开发。

在使用 Spring 框架时,我们需要决定是使用 XML 文件配置相关的 Bean 还是使用注解来注册相关的 Bean ,前者对于有大量的 Bean 的工程十分不友好,而后者又会使相关注解分散到工程代码中,不利于整体管理。但是,在 Servlet 3.0 规范提出后,Web 容器也不必依赖 web.xml 文件进行部署了,并且注解功能也逐渐强大到可以摆脱 XML 配置文件。

在 Spring 4.x 版本足以摆脱 XML 配置后,基于注解可以进一步简化使用 Spring 框架时的开发工作,为此,在 2014 年 Spring Boot 1.0 版本推出。它并不是要替代 Spring 框架,而是为了简化 Spring 框架的使用。其通过注解默认了常用的配置,使得开发人员可以快速的进行开发、测试及部署。即便不进行任何配置,Spring Boot 的自动装配组件和默认配置也能保证程序的运行,所以说约定优于配置是 Spring Boot 的主导思想。

核心技术

Spring 的核心技术是 IoC 和 AOP,基于此设计出了 Spring MVC、Spring JDBC、Spring Security 等框架。在使用 Spring 框架后,通过注解来定义 Servlet 、HandlerInterceptor、Filter、Bean 等,可以简化配置工作。但是,可以更进一步,使用 Spring MVC 框架,使用 SerlvletDispatch 来分发请求,如此可以减少 Servlet 的创建及配置。这么做的直接好处便是消减了 Web 容器中的实例,业务调用尽可能的限制在 EJB 容器中的 Bean 之间。

IoC

IoC(Inversion of Control)控制反转,是面向对象编程的一种设计模式,其基础是反射编程,而反射编程通过字符串来创建对应的类对象,本身就可以降低代码的耦合度。IoC 除了常用的依赖注入实现方式外,还有依赖查找方式。

  • 依赖注入(Dependency Injection)是由容器负责组件的装配,其会将组件依赖的对象通过赋值方法或构造器方法传递给组建,所以叫依赖注入。

  • 依赖查找(Dependency Lookup)是由组件调用容器接口发起依赖对象的查找,而容器将调用组件实现的指定接口回传资源。

AOP

AOP(Aspect Oriented Programming)面向切面编程,是切面类和目标类的交融,目的是在目标类中的指定方法前后执行需要的操作。

一个切面,可以有多个切点,切点描述了切入的目标类中的方法,这个描述可以是通配的,即切点可以对应多个目标类中的多个方法,也可以是某个类中的一个方法。这就意味着我们可以为一个或者一类方法约定统一的操作,如进行日志的记录、资源的分配和回收。

在切面类中的方法分为 5 类,这 5 类方法分别对应切入目标方法中的不同时机,即对于每一个切入点都可以按需要约定这 5 种时机时要执行的操作。

  • 目标方法之前执行的方法
  • 环绕目标执行的方法,该方法中需要使用 ProceedingJoinPoint 入参主动调用目标方法
  • 在目标方法结束前要执行的方法,指目标方法在返回或抛出异常前执行的方法,类似于 finally 中的代码
  • 目标方法正常返回后执行的方法
  • 目标方法抛出异常执行的方法

下面是切面编程切面类,切点及切点关联方法的配置样例:

<?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-4.3.xsd  
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
 
 <bean id="carDao" class="com.ssm.aspectj.CarDaoImpl"></bean>
 
 <bean id="myAspect" class="com.ssm.aspectj.MyAspect"></bean>
 
 <aop:config>
 
 	<aop:aspect id="aspect" ref="myAspect">
 	
 		<aop:pointcut id="myPointCut" 
 				expression="execution(* com.ssm.aspectj.CarDaoImpl.*(..))" />
 
 		<aop:before method="myBefore" pointcut-ref="myPointCut" />
 		<aop:after-returning method="myAfterReturning" returning="returnval" 
 				pointcut-ref="myPointCut"/>
 		<aop:around method="myAround" pointcut-ref="myPointCut" />
 		<aop:after-throwing method="myAfterThrowing" 
 				pointcut-ref="myPointCut" throwing="throwable" />
 		<aop:after method="myAfter" pointcut-ref="myPointCut" />
 
 		<aop:pointcut id="myPointCut1" 
 				expression="execution(* com.ssm.aspectj.CarDaoImpl.deleteCar(..))" />
 		<aop:around method="myAround" pointcut-ref="myPointCut1" />
 
 	</aop:aspect>
 
 </aop:config>
 </beans>

实际上,使用下面的注解可以快速实现一个切面类及关联的切点:

注解说明
@Aspect定义切面类
@Pointcut定义切点,通过一个空方法来声明切点名称
@Before定义目标方法前执行的方法
@After定义目标方法最后执行的方法
@Around定义目标方法环绕执行的方法
@AfterReturning定义目标方法返回后执行的方法
@AfterThrowing定义目标方法异常抛出时执行的方法
增强

使用 @DeclareParents 注解可以为指定的类引入新的类来增强其功能,其实现原理是在于 AOP 生成的代理对象会作为该接口的实现,从而使得代理可以使用该接口的方法。

如下面的例子,声明一个原有类 CarDaoImpl 和增强类 CarValidatorImpl,并定义一个 MyAspect 切面类,指定增强关系。

@Repository("carDao")
public class CarDaoImpl implements CarDao {

	@Override
	public void addCar() {

		System.out.println("add car");

	}
}	

public class CarValidatorImpl implements CarValidator {

	@Override
	public void validate() {
		System.out.println("validate execute");
	}

}

@Component
@Aspect
public class MyAspect {
	
	@DeclareParents(value = "com.ssm.aspectj.CarDaoImpl",
			defaultImpl = CarValidatorImpl.class)
	public CarValidator carValidator;
	
	
	@Pointcut("execution(* com.ssm.aspectj.*.*(..))")
	private void myPointCut() {
		
	}
	
	@Before("myPointCut()")
	public void myBefore(JoinPoint joinPoint) {
		System.out.println("before execute , target : " +
				joinPoint.getTarget() + " method : " + 
				joinPoint.getSignature().getName());
	}
}	

测试如下,可以对 CarDao 强制转换为 CarValidator 后使用相关方法。

public class AspectjTest {

	public static void main(String[] args) {
		
		CarDao carDao = (CarDao) applicationContext.getBean("carDao");
		carDao.addCar();
		
		System.out.println("=========");
		
		CarValidator carValidator = (CarValidator)carDao;
		carValidator.valide();
		
	}
}
在学习Spring框架的过程中,我进行了一些实验,下面是我的小结与思考: 1. 实验内容:使用Spring MVC框架搭建一个简单的Web应用程序。在这个应用程序中,我使用了Spring MVC的各种功能,如控制器、视图解析器、数据绑定等。 2. 实验结果:通过这个实验,我深入了解了Spring MVC框架的工作原理和各种功能。同时,我也学会了如何使用Spring MVC来构建一个简单的Web应用程序。 3. 实验内容:使用Spring Boot框架快速搭建一个Web应用程序。在这个应用程序中,我使用了Spring Boot的各种功能,如自动配置、启动器、命令行界面等。 4. 实验结果:通过这个实验,我深入了解了Spring Boot框架的工作原理和各种功能。同时,我也学会了如何使用Spring Boot来快速搭建一个Web应用程序。 5. 实验内容:使用Spring Data框架访问数据库。在这个实验中,我使用了Spring Data JPA和Spring Data MongoDB两个模块来访问MySQL和MongoDB数据库。 6. 实验结果:通过这个实验,我深入了解了Spring Data框架的工作原理和各种功能。同时,我也学会了如何使用Spring Data来访问不同类型的数据库。 总的来说,通过这些实验,我深入了解了Spring框架的各种功能和工作原理。同时,我也学会了如何使用Spring框架来构建一个真正的企业级应用程序。虽然在实验过程中遇到了一些问题和挑战,但是通过不断的尝试和学习,我最终成功地完成了这些实验。这些实验让我对Spring框架有了更深入的认识,并且也为我今后的工作和学习打下了坚实的基础。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值