01 Spring与SpringMVC回顾

前言

SpringBoot本身没有增加任何新的技术,其是对Spring开发方式的一种简化。

Spring的出现,本身是为了简化JavaEE的开发。

可是随着Spring体系的不断壮大,Spring本身也被各种配置所拖累,有戏言称:Spring开发就是一本java一半xml。

SpringBoot则利用Spring4开始提供的条件注解,大大简化了Spring项目的开发。

现在的开发人员是幸福的,从语言到工具链,以及现在的网络环境和学习环境,只要想学,就能有所收获。

本文梳理一下Spring和SpringMVC的核心功能,并不对基础概念进行解释。建议在学习Spring之前,小伙伴需要对Spring有所了解。

Spring核心

Spring框架设计原则

Spring的出现了为了简化JavaEE开发,其在设计过程中遵循了一些基础原则

  • 使用POJO进行轻量级和最小侵入式开发
  • 通过依赖注入和基于接口编程实现松耦合
  • 通过AOP和默认习惯进行声明式编程
  • 使用AOP和 模板减少模式化代码

控制反转与依赖注入

名词解释

  • 什么是控制反转

在编写Java代码时,最长做的操作可能就是获取一个对象了,在原始阶段,我们可能使用new关键字创建一个对象,当然,也有通过工厂模式获取对象的。

但不管怎么说,这个对象是我们自己来的。

而在Spring中,我们是在编写一个个组件,组件编写完毕后交给Spring管理,在需要用到的地方只要一声,由Spring负责对象的初始化。

将对象由原先自己创建,改变为使用Spring管理的过程,这就是控制反转

  • 什么是依赖注入

Spring根据我们的说明,将合适的对象交给我们进行使用,这个就是依赖注入。

核心注解

在控制反转与依赖注入过程中,我们会用到一些注解

声明Bean:@Component、@Service、@Repository、@Controller

注入Bean:@Autowired、@Inject、@Resource

@Configuration:声明当前类是一个配置类

@ComponentScan:扫描Bean,将被扫描到的Bean初始化后纳入Spring容器进行管理

面向切面编程

面向过程和面向对象,是我们比较熟悉的两种编程范式。

面向切面也一样,也是一种编程范式。

其不是对其它编程范式的颠覆,只是一个有益的补充。有其合适的适用场景。

举个例子,我们希望在特定方法调用前和调用后,将调用的方法参数和返回值进行答应。这个时候使用AOP做就非常方便。否则我们就需要手动在方法内部进行日志的打印。

SpEL表达式

  • 将固定的字符串注入给成员变量
@Value("普通字符串注入")
private String str;
  • 使用SpEL表达式获取系统属性进行注入
@Value("#systemProperties['os.name']")
private String osName;
  • 使用SpEL表达式生成一个随机数
@Value("#{T(java.lang.Math).random()*100.0}")
private double randomNumber;
  • 注入其他Bean的属性
@Value("#{demoService.property}")
  • 注入文件
@Value("classpath:com/ist/a.txt")
private Resource resource;
  • 注入网络资源
@Value("http://www.baidu.com")
private Resource resource;
  • 注入属性文件的键值
@Value("${book.name}")
private String st;
  • 注入配置文件
@Autowired
private Environment env;

将当前类使用的配置文件注入给env,调用env.getProperty("book.name)"),就能够获取数据

Bean的生命周期

有时候在Bean初始化和销毁的时候需要做一些事情

  • 在使用@Bean注解的时候,通过initMethod和destoryMethod属性指定
  • 在Bean中,使用@PostConstruct(在构造函数执行完后执行)和@PreDestory
    ​ (在Bean销毁前执行)如果使用第二种方式,那么需要添加JSR-250支持
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>jsr250-api</artifactId>
    <version>1.0</version>
</dependency>

一般使用initMethod和destoryMethod就行了

异步方法

使用多线程,实现方法的异步调用

1、配置一个线程池

package cfg.spring;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
 * Created by nbcoolkid on 2017-05-20.
 */
@Configuration
@EnableAsync
public class TaskExecConf implements AsyncConfigurer{
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(10);
        threadPoolTaskExecutor.setQueueCapacity(25);
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
@Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

2、在配置类中使用@EnableAsync开启对异步任务的支持

在执行Bean中使用@Async注解声明其是一个异步任务,如果标注在类上,说明这个类的所有方法都是异步的

定时任务

对于一些简单的定时任务,Spring也有自己的实现

使用方法:

1、在配置类上使用@EnableScheduling开启支持

2、在任务方法上使用@Scheduled,使用core表达式设置时间

package org.zln.spb.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.zln.spb.ann.Task;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Task
public class Demo01Task {
    @Scheduled(cron = "0/5 * * * * ? ")
    public void showH() {
        System.out.println("定时任务执行---");
    }
}

这里的@Task注解是一个自定义注解

package org.zln.spb.ann;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Task {
    String value() default "";
}

package org.zln.spb.task;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Configuration
@EnableScheduling
@ComponentScan
public class TaskConfig {
}
package org.zln.spb.task;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TaskConfig.class);
        Thread.sleep(1000 * 3600);
    }
}

小结

Spring的内容当然不止这么些,但是有些内容在SpringBoot中会深入讲解,有些内容已经过时,这里就不再深入展开了。

SpringMVC核心

MVC模式思想

如果编写过非MVC模式的后端代码,直接用servlet api进行业务逻辑的实现。

一定能够深刻的体会到MVC对后端开发带来的巨大好处。

所谓MVC,就是将后端处理组件划分为了模型、视图、控制器,每个组件有自己的功能场景,在代码上进行了分层。使得逻辑更加清晰

@ControllerAdvice

控制器增强,一般用于控制器的全局配置。

我经常用到的一个功能就是使用@ControllerAdvice来捕获全局的异常

文件上传

所有的MVC框架都会讲到文件上传。

因为SpringBoot中有更简洁的方式,这里就不讲了

HttpMessageConverter

服务端推送技术:SSE

小结

写这篇文章,主要是为了对Sping的常见知识点做一个维护,为后续SpringBoot的展开做一个基础。

加粗样式

猜你喜欢

转载自blog.csdn.net/m0_37208669/article/details/85226354