Spring框架使用
前言
spring是一个轻量的、开源的企业级程序开发框架,通过提供基础设施支持,提供内置的设计模式,简化了复杂的企业开发过程。
总之它可以高效完成各种任务,提高开发效率和代码质量。
处理事务管理
事务管理的两种事务:声明式事务与编程式事务
声明式事务:
通过配置去实现,我们只需要使用切面注解来实现事务管理功能@Transactional
- 引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>{版本号}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>{版本号}</version>
</dependency>
- 代码示例
@Service
@Transactional
public class ExampleServiceImpl implements ExampleService {
@Override
public void doSomething() {
// 业务逻辑处理
...
}
}
编程式事务:
使用spring提供的事务管理器接口PlatformTransactionManager去实现提供了事务的提交,回滚。
/**
这块就是注入PlatformTransactionManager的内容
//引入事务管理器
@Autowired
private ApplicationContext applicationContext;
//创建事务定义
PlatformTransactionManager transactionManager = applicationContext.getBean(PlatformTransactionManager.class);
**/
//在这里就直接引入了事务定义了
@Autowired
private PlatformTransactionManager transactionManager;
public void doSomething() {
//开启事务
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 业务逻辑处理
...
transactionManager.commit(status);
} catch (Exception ex) {
transactionManager.rollback(status);
throw ex;
}
}
框架核心
框架的核心是IOC(控制反转)与AOP(面向切面的编程),下面我先介绍里面常用的注解然后再去了解
常见注解
- @Controller、@Service、@Mapper、@Repository、@Component、@Bean、@Configuration:标记在SpringMVC中的各个控制器,都被注解为Spring Bean组件,可以通过@Autowired去自动装配这些组件
- @Autowired:这些注解主要是用于去指定bean的注入与使用
- AOP相关注解
- 事务相关注解
- @RequestMapping、@ResponsBody(web相关注解):数据的请求与接收
AOP( 面向切面编程)
首先它最重要的一种思想就是代理模式,它与 OOP( 面向对象编程) 相辅相成,它们的单位不同
- OOP 中, 我们以类(class)作为我们的基本单元,
- AOP 中的基本单元是 Aspect(切面)
切面和通知有哪些类型?
切面可以理解为是切点(那个类与方法需要被拦截)与通知(具体的逻辑实现)的合集
简单理解来说就是切面就是这个地方需要什么横切逻辑,而通知就是这个地方需要用什么具体的逻辑。
放个图了解一下啊
下面是常见的切面类型
切面的类型
- 前置通知(@Before):目标方法前执行
- 后置通知(@After):(后执行)
- 返回通知(@AfterReturning):返回结果后执行
- 异常通知(@AfterThrowing):抛出异常后执行
- 环绕通知(@Around):目标方法执行前后都执行(可以控制目标方法的执行过程)
通知类型
- 前置通知
- 后置通知
- 异常抛出通知
- 方法环绕通知
AOP实现
-
定义切点(在spring中一般使用注解的方式去定义切点,并且去注释那些需要去实现)
execution([访问修饰符] [返回类型] [包名].[类名].[方法名](..)
-
实现通知:这里写具体的实现逻辑,通俗点讲这就是要写插入的代码
下面我举一个环绕通知(代码执行前后都要去执行)的栗子:// 这里需要将切点给导入 @Around("servicePointcut()") public void beforeAdvice(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("Around calling method: " + methodName); }
JoinPoint 利用反射与动态代理来获取各种信息
- 获取被拦截方法的名称、类型、参数名数组
String methodName = joinPoint.getSignature().getName();
signature.getReturnType().toString(); // 返回类型
signature.getParameterNames(); // 参数名数组- 获取被拦截方法的参数列表
Object[] args = joinPoint.getArgs();- 获取被拦截方法所在的类
Class<?> targetClass = joinPoint.getTarget().getClass();
- 声明切面:从上面的概念我们知道切面其实就是切点与通知的组合,那么我们这里要做的就是将这两个进行组合。下面是代码示例(@Aspect):这里的代码就直接使用component进行添加到bean容器中,不需要再去配置。
@Aspect @Component public class ExampleAspect { @Around("servicePointcut()") public void beforeAdvice(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("Around calling method: " + methodName); } }
- 目标实现:这里就是将具体的目标进行实现具体的业务逻辑。
@Service public class ExampleServiceImpl implements ExampleService { public void doSomething() { System.out.println("doing something..."); } }
- 启动类添加相关注解
@EnableAspectJAutoProxy
使用场景
使用AOP主要是为了将业务功能与通用功能给抽取出来,从而提高代码的可读性与可复用性。
- 权限控制
- 日志管理
- 缓存控制
- 异常控制
IOC(管理所有的JavaBean)
IOC是一种设计模式的思想,它的核心就是将两个类之间的依赖关系从编码时确定变为运行时动态确定工厂类,实例化对象,管理对象之间的依赖关系。
依赖注入(DI)
DI实际上是ioc的一种实现方式。
通过容器自动将一个对象依赖的其他对象注入到这个对象中,实现松耦合。
优势
要了解这个的优势,就需要知道在之前遇到这些问题时候如何去处理:
在之前程序员通常需要通过手动的方式去管理对象之间的依赖关系的。
当一个对象需要另一个对象时,程序员会手动创建该对象并将其传递给需要它的对象。
如何实现:主要是两种实现方式
下面演示在一个MVC中的使用案例
公共代码
-
定义Service接口规范
public interface UserService { String getInfo(); }
-
接口实现类
public class UserServiceImpl implements UserService { public String getInfo() { return "User information"; } }
-
controller实现类
public class UserController { private final UserService service; // 使用构造器注入 public UserController(UserService service) { this.service = service; } public void showInfo() { System.out.println(service.getInfo()); } }
xml
通过定义bean的标签来管理容器及其属性,并使用依赖注入的方式来装配这些类和属性。
示例:先使用xml将上面的实现注入
<bean id="userService" class="com.example.UserServiceImpl"/>
<bean id="userController" class="com.example.UserController">
<constructor-arg ref="userService"/>
</bean>
下面我们在使用java实现类
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserController controller = (UserController) context.getBean("userController");
controller.showInfo(); // 输出 "User information"
注解
注解相比于xml的最大优势就是可以简化开发、更加直观灵活
示例:还是将上述代码注入并实现
- 直接在实现类上面添加@Component注解,这个注解就会被扫描到
@Component public class UserServiceImpl implements UserService { public String getInfo() { return "User information"; } }
- 然后我们在实现类中在使用@Autowired注入到实现代码中,在直接调用里面的方法
@Component public class UserController { @Autowired private UserService service; // ... }
总结
学会这些思想和技术的应用可以帮助开发者提高代码的质量和执行效率,更好地完成各种任务。
最后希望能帮到大家,你们的点赞是我写优质博客的最大动力~~