示例:spring xml+注解混合配置

以下是一个 Spring XML + 注解的混合配置示例,结合了 XML 的基础设施配置(如数据源、事务管理器)和注解的便捷性(如依赖注入、事务声明)。所有业务层代码通过注解简化,但核心配置仍通过 XML 管理。


1. 项目结构

复制代码
src/main/java
├── com.example.dao
│   └── UserDao.java           # DAO 接口
│   └── impl
│       └── UserDaoImpl.java   # DAO 实现类(注解驱动)
├── com.example.service
│   ├── UserService.java       # Service 接口
│   └── impl
│       └── UserServiceImpl.java # Service 实现类(@Service + @Transactional)
└── com.example.controller
    └── UserController.java    # Controller 类(@Controller)
resources
├── applicationContext.xml     # Spring 主配置文件
└── db.properties              # 数据库配置文件

2. XML 配置 (applicationContext.xml)

xml 复制代码
<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 1. 启用组件扫描(自动发现 @Component, @Service, @Repository, @Controller) -->
    <context:component-scan base-package="com.example"/>

    <!-- 2. 数据源配置(通过 properties 文件注入) -->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 3. JdbcTemplate 配置(用于 DAO 层) -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 4. 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 5. 启用注解驱动的事务管理(@Transactional) -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

3. DAO 层(注解驱动)

接口 (UserDao.java)
java 复制代码
package com.example.dao;

import com.example.model.User;
import org.springframework.stereotype.Repository;

@Repository // 标记为 DAO 组件,自动被组件扫描发现
public interface UserDao {
    User findById(int id);
}
实现类 (UserDaoImpl.java)
java 复制代码
package com.example.dao.impl;

import com.example.dao.UserDao;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository // 替代 XML 中的 <bean> 定义
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public User findById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) ->
            new User(rs.getInt("id"), rs.getString("name"))
        );
    }
}

4. Service 层(注解驱动 + 事务)

接口 (UserService.java)
java 复制代码
package com.example.service;

import com.example.model.User;

public interface UserService {
    User getUserById(int id);
}
实现类 (UserServiceImpl.java)
java 复制代码
package com.example.service.impl;

import com.example.dao.UserDao;
import com.example.model.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; // 声明事务

@Service // 替代 XML 中的 <bean> 定义
@Transactional // 默认事务配置(REQUIRED 传播行为)
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public User getUserById(int id) {
        return userDao.findById(id);
    }
}

5. Controller 层(注解驱动)

类 (UserController.java)
java 复制代码
package com.example.controller;

import com.example.model.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController // 替代 XML 中的 <bean> 定义
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable int id) {
        return userService.getUserById(id);
    }
}

6. 模型类 (User.java)

java 复制代码
package com.example.model;

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter 和 Setter 省略
}

7. 数据库配置 (db.properties)

properties 复制代码
jdbc.url=jdbc:mysql://localhost:3306/testdb
jdbc.username=root
jdbc.password=secret

8. 启动应用

主类 (Application.java)
java 复制代码
package com.example;

import com.example.controller.UserController;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {
    public static void main(String[] args) {
        // 初始化 Spring 上下文(仅加载 XML 配置)
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 通过组件扫描自动发现 UserController
        UserController userController = context.getBean(UserController.class);
        User user = userController.getUser(1);
        System.out.println("User: " + user.getName());

        // 关闭上下文
        context.close();
    }
}

关键点说明

  1. 混合配置的优势

    • XML:管理数据源、事务管理器等基础设施。
    • 注解 :简化业务层的依赖注入(@Autowired)和事务声明(@Transactional)。
  2. 组件扫描

    • <context:component-scan> 自动发现 @Component@Service@Repository@Controller 注解的类,无需 XML 定义 Bean。
  3. 事务管理

    • <tx:annotation-driven> 启用 @Transactional 注解,替代 XML 中的 AOP 事务配置。
  4. 依赖注入

    • 所有依赖通过 @Autowired 注入,无需 XML 中的 <property> 标签。

常见问题排查

  1. Bean 未找到

    • 检查 <context:component-scan> 的包路径是否包含所有组件。
    • 确保类上有正确的注解(如 @Service@Repository)。
  2. 事务不生效

    • 检查 @Transactional 是否添加到 public 方法。
    • 确保 <tx:annotation-driven> 已配置且事务管理器正确。
  3. 数据库连接失败

    • 检查 db.properties 中的 URL、用户名和密码。
    • 确保数据库驱动已添加到依赖(如 MySQL 的 mysql-connector-java)。

通过这种混合模式,既能享受 XML 的集中式基础设施配置,又能利用注解简化业务层代码,是传统 Spring 项目的推荐实践。

相关推荐
Leaf吧7 分钟前
java 设计模式 原型模式
java·设计模式·原型模式
super凹凸曼11 分钟前
分享一个把你的API快速升级为MCP规范的方案,可在线体验
java·后端·开源
howeres25 分钟前
Spring Boot 应用优雅关闭
java·spring boot
码上飞扬32 分钟前
用Java实现简易区块链:从零开始的探索
java·区块链·哈希算法
南汐以墨36 分钟前
Maven与Springboot创建
java·spring boot·maven
Non importa1 小时前
【C++】新手入门指南(下)
java·开发语言·c++·算法·学习方法
创码小奇客1 小时前
MongoDB 索引操作:数据世界的超速导航指南
java·mongodb·trae
秋野酱1 小时前
基于javaweb的SpringBoot儿童爱心管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
头顶秃成一缕光1 小时前
TCP的三次握手和四次挥手
java·服务器·tcp/ip·软件工程
苏格拉没有底_coder1 小时前
【EasyPan】项目常见问题解答(自用&持续更新中…)
java