Spring 纯注解配置与 SpringBoot 入门详解

一、Spring 纯注解配置

1.1 为什么要使用纯注解配置

传统 Spring 开发中,我们依赖大量 XML 配置(如数据源、MyBatis、事务、SpringMVC 等),这些配置重复且繁琐。纯注解配置可以完全替代 XML,让配置更简洁、更贴合 Java 编码习惯。

需要改造的核心 XML 配置场景:

  • JDBC 数据源配置
XML 复制代码
<context:property-placeholder location="classpath:db.properties">
</context:property-placeholder>
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
      destroy-method="close">
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="maxActive" value="10" />
    <property name="minIdle" value="5" />
</bean>
  • MyBatis 相关配置
XML 复制代码
    <!--sqlSession工厂-->
    <bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="typeAliasesPackage" value="com.hg.pojo"></property>
    </bean>

    <!--配置MapperScan扫描mapper接口,并把生成的代理类交给spring去管理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.hg.mapper"></property>
        <property name="sqlSessionFactoryBeanName" value="sessionFactoryBean"></property>
    </bean>
  • 事务管理配置
XML 复制代码
<bean id="transactionManager" 
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启spring对注解事务的支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
  • Service/Controller 包扫描

    XML 复制代码
        <!--扫描service-->
        <context:component-scan base-package="com.hg.service"></context:component-scan>
  • SpringMVC 核心配置

    XML 复制代码
    <!--配置springmvc要扫描的包-->
        <context:component-scan base-package="com.hg.controller,com.hg.exception"></context:component-scan>
    
        <!--开启注解驱动:配置handlerMapping和handlerAdapter-->
        <mvc:annotation-driven conversion-service="cs"></mvc:annotation-driven>
    
        <!--配置日期转换器-->
        <bean id="cs" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <bean class="com.hg.converter.MyDateConverter"></bean>
                </set>
            </property>
        </bean>
    
        <!--配置视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/pages/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    
        <!--配置文件上传解析器-->
        <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="5242880" />
            <property name="defaultEncoding" value="UTF-8" />
        </bean>
        <!--资源映射器:直接放行无须dispatcherServlet去处理-->
        <mvc:resources location="/head/" mapping="/head/**"/>
    
        <!--配置拦截器-->
        <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/account/**"/>
                <mvc:exclude-mapping path="/user/**"></mvc:exclude-mapping>
                <bean class="com.hg.interceptor.LoginInterceptor"></bean>
            </mvc:interceptor>
        </mvc:interceptors>
  • web.xml 容器配置

    XML 复制代码
    <!--配置监听器:监听tomcat启动,加载spring配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext-*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
    <!--前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

1.2 核心注解说明

注解 作用 属性
@Configuration 标识当前类是spring的配置类,可替换xml配置文件 等价于applicationContext.xml
@ComponentScan 指定 Spring 初始化容器时扫描的包,替代<context:component-scan> basePackages:指定扫描包
@Bean 把实体bean装到iocMap(容器),等价于<bean/> value:指定iocMap的key
@PropertySource 加载 properties 配置文件,替代<context:property-placeholder> value:文件路径
@Import 导入其他配置类,等价于<import/> value:配置类字节码

1.3 分模块纯注解配置实现

1.3.1 JDBC 配置(JdbcConfig.java)

加载数据库配置文件,创建数据源 Bean:

java

复制代码
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
 
@PropertySource("classpath:db.properties")
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")
    public DataSource getDatasource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
1.3.2 MyBatis 配置(MyBatisConfig.java)

配置 SqlSessionFactory 和 Mapper 扫描:

复制代码
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
 
public class MyBatisConfig {
    @Bean
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setDataSource(dataSource);
        ssfb.setTypeAliasesPackage("com.hg.pojo");
        return ssfb;
    }
    
    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.hg.mapper");
        msc.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        return msc;
    }
}
1.3.3 事务配置(TxConfig.java)

开启事务注解并配置事务管理器:

复制代码
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
public class TxConfig {
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DruidDataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
1.3.4 Service 配置(ServiceConfig.java)

扫描 Service 层组件:

复制代码
import org.springframework.context.annotation.ComponentScan;

@ComponentScan("com.hg.service")
public class ServiceConfig {
}
1.3.5 核心 Spring 配置(SpringConfig.java)

整合所有子配置类:

复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({JdbcConfig.class, MyBatisConfig.class, ServiceConfig.class, TxConfig.class})
public class SpringConfig {
}
1.3.6 SpringMVC 配置(SpringMvcConfig.java)

替代 springmvc.xml,配置视图解析器、拦截器、静态资源等:

复制代码
import com.hg.converter.DateConverter;
import com.hg.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan({"com.hg.controller","com.hg.exception"})
@EnableWebMvc
public class SpringmvcConfig implements WebMvcConfigurer {

    // 日期转换器
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new DateConverter());
    }

    // 视图解析器
    @Bean
    public InternalResourceViewResolver internalResourceViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    // 文件上传解析器
    @Bean
    public CommonsMultipartResolver multipartResolver(){
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setMaxUploadSize(5242880);
        resolver.setDefaultEncoding("UTF-8");
        return resolver;
    }

    // 静态资源映射
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/head/**").addResourceLocations("/head/");
    }

    // 拦截器配置
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/account/**")
                .excludePathPatterns("/user/**");
    }
}
1.3.7 Web 容器配置(WebConfig.java)

替代 web.xml,配置 Spring/SpringMVC 容器和过滤器:

复制代码
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    // 加载Spring核心配置类
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
    
    // 加载SpringMVC配置类
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
    
    // 设置SpringMVC拦截路径
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    
    // 配置中文乱码过滤器
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }
}
1.3.8 清理 XML 文件

删除所有 XML 配置文件(applicationContext-*.xml、springmvc.xml,web.xml 仅保留欢迎页配置):

xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

二、SpringBoot 入门

2.1 什么是 SpringBoot(重点)

SpringBoot (spring+springmvc) 是 Pivotal 团队推出的快速开发 Spring 应用的框架,并非增强 Spring 功能

特点

  • 内置 Tomcat等 Servlet 容器
  • 简化 Maven配置(Starter 启动器)
  • 自动配置 Spring ,无需手动 XML 配置

2.2 构建 SpringBoot 项目

2.2.1 方式 1:官网生成

访问http://start.spring.io/ ,选择 Maven、SpringBoot 版本、项目信息,点击 GENERATE 下载项目压缩包。

2.2.2 方式 2:手动创建 Maven 项目
  1. 创建空 Maven 工程,不使用骨架;
  2. 修改 pom.xml,继承 SpringBoot 父工程:

pom.xml

复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/>
</parent>
  • 添加编码格式:

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  • 添加 Web 启动器依赖:

    <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
  • 创建启动类(核心):

java

运行

java 复制代码
​
package com.hg;    //必须是controller、service、mapper的上级目录

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

​

2.3 SpringBoot Starter 启动器

2.3.1 解决的问题
  • 依赖管理:自动导入功能所需的所有 jar 包,避免手动导入冲突
  • 自动配置:无需手动配置,框架自动完成核心配置
  • Starter : 是一堆依赖和配置类的集合
2.3.2 Starter 命名规范
  • 官方:spring-boot-starter-模块名(如spring-boot-starter-webspring-boot-starter-jdbc
  • 第三方:模块名-spring-boot-starter(如mybatis-spring-boot-starter

2.4 HelloWorld 示例

2.4.1 编写 Controller

java

复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;

@Controller
public class HelloWorld {
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String, Object> hello() {
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
}
2.4.2 启动类位置要求

启动类需放在 Controller 的同级包或上级包中,否则无法扫描到 Controller。

2.4.3 自定义 Banner(可选)
  1. 访问banner生成网站:http://www.bootschool.net/ascii 生成自定义字符画;
  2. 将内容保存为banner.txt放在 resources 目录下,启动项目即可生效。
  3. 效果:

2.5 全局配置文件

SpringBoot 提供application.propertiesapplication.yml全局配置文件(放在 resources 目录),用于覆盖默认配置。

2.5.1 properties 格式

properties

复制代码
# 修改端口
server.port=8888
# 修改上下文路径
server.servlet.context-path=/springboot
2.5.2 yml 格式(推荐)

YML 具备天然树状结构,语法规则:

  • :分割键值对,冒号后必须加空格;
  • 缩进用空格(禁止 Tab),左对齐为同一层级;

yaml

复制代码
server:
  port: 8090
  servlet:
    context-path: /springboot

2.6 项目发布方式

2.6.1 Jar 包发布(推荐)
  1. pom.xml 添加构建插件:

xml

复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  1. 执行mvn package打包,生成xxx.jar
  2. 终端执行java -jar xxx.jar启动项目。
2.6.2 War 包发布
  • 修改打包方式为 war:

xml

复制代码
<packaging>war</packaging>
  • 排除内置 Tomcat(避免冲突):

xml

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
  • 自定义 War 包名称:

xml

复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <warName>hello</warName>
    </configuration>
</plugin>
  • 修改启动类继承SpringBootServletInitializer

java

复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  • 执行mvn package打包,将 War 包放入外部 Tomcat 的 webapps 目录启动。
相关推荐
qqacj2 小时前
SpringBoot Test详解
spring boot·后端·log4j
ADRU2 小时前
SSE 到底是什么?它和 HTTP 有什么关系?Java/Spring 怎么实现流式输出(可直接上手)
java·spring·http
暮冬-  Gentle°2 小时前
C++中的空对象模式变体
开发语言·c++·算法
二闹2 小时前
解锁Python的隐藏管家:with语句的原理与用法
后端·python·设计
de_wizard2 小时前
Spring Boot 整合 Keycloak
java·spring boot·后端
m0_579393662 小时前
C++中的命令模式
开发语言·c++·算法
吴声子夜歌2 小时前
JavaScript——DOM与事件
开发语言·javascript·ecmascript
Re_zero2 小时前
throws 还是 try-catch?Code Review 里被我打回最多的异常处理
java·代码规范
胡楚昊2 小时前
BUUCTF RE 看心情写(2)
开发语言·c#