Spring框架(一)

发布于:2025-05-11 ⋅ 阅读:(24) ⋅ 点赞:(0)

        Spring框架是Java开发中最为流行的框架之一,它以其强大的功能和灵活的设计,极大地简化了企业级应用的开发。本文将详细介绍Spring框架的核心概念、核心技术、依赖注入、多配置文件方式、开发程序的方式、IOC注解方式以及Spring与JUnit的整合。

目录

一、Spring框架概述

1.1 Spring框架的概述

1.2 Spring框架的优点

二、Spring的IOC核心技术

2.1 什么是IOC

2.2 IOC的程序入门

2.3 IOC技术总结

2.4 实例化Bean对象的三种方式

三、DI依赖注入

3.1 依赖注入的概述

3.2 DI的两种方式

3.3 复杂类型注入(数组,集合,Properties)

四、多配置文件管理

五、Spring框架开发程序的方式

六、IOC注解开发

6.1 半注解方式(XML + 注解)

6.2 纯注解方式(零XML)

6.3 对比分析

七、Spring 框架整合 JUnit 单元测试

7.1 基于XML配置的Spring整合JUnit测试

7.2 纯注解方式的Spring整合JUnit测试

7.3 对比分析

总结


一、Spring框架概述

1.1 Spring框架的概述

        Spring是一个开源的Java平台,提供了一个轻量级的框架来解决企业应用开发的复杂性。Spring框架的核心优势在于其分层架构,允许开发者选择使用特定的组件,同时为J2EE应用程序开发提供集成的解决方案。

Spring框架的主要特点包括:

  • ​控制反转(IoC)​​:将对象的创建和依赖关系的管理交给Spring容器。

  • ​面向切面编程(AOP)​​:通过AOP实现权限拦截、运行监控等功能。

  • ​声明式事务管理​​:通过配置文件实现事务管理,无需手动编写事务代码。

  • ​方便程序测试​​:支持JUnit4,便于对Spring程序进行单元测试。

  • ​集成优秀框架​​:如Struts2、Hibernate、MyBatis、Quartz等。

  • ​降低JavaEE API的使用难度​​:对JDBC、JavaMail等复杂API进行了封装。

1.2 Spring框架的优点

  • ​方便解耦,简化开发​​:Spring通过IoC容器管理对象的创建和依赖关系,开发者无需手动管理对象的生命周期和依赖关系。

  • ​AOP编程的支持​​:Spring提供了AOP编程的支持,可以方便地实现权限拦截、运行监控等功能。

  • ​声明式事务的支持​​:通过配置文件即可完成事务管理,无需手动编写事务管理代码。

  • ​方便程序的测试​​:Spring对JUnit4提供了良好的支持,可以通过注解方便地测试Spring程序。

  • ​方便集成各种优秀框架​​:Spring内部提供了对Struts2、Hibernate、MyBatis、Quartz等框架的直接支持。

  • ​降低JavaEE API的使用难度​​:Spring对JDBC、JavaMail、远程调用等复杂API进行了封装,降低了使用难度。

二、Spring的IOC核心技术

2.1 什么是IOC

        IOC(Inverse of Control,控制反转)是一种设计原则,通过将对象的创建权反转给Spring框架,降低了代码之间的耦合度。Spring的工厂通过读取配置文件来管理对象的创建和依赖关系。

2.2 IOC的程序入门

以下是一个简单的Spring IOC入门示例:

1. 创建mavenJava项目,导入坐标依赖(pom.xml)

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2. 编写接口和实现类

package com.qcby.service;

public interface UserService {
    public void hello();
}
package com.qcby.service;

public class UserServiceImpl implements UserService{
    public void hello() {
        System.out.println("Hello IOC!");
    }
}

3. 编写 Spring 核心的配置文件

在src/main/resources文件夹下创建spring.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--IOC 管理 bean-->
    <bean id="userService" class="com.qcby.service.UserServiceImpl"/>

</beans>

4. 编写测试方法

import com.qcby.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo1 {
    /**
     * 入门程序
     */
    @Test
    public void run1(){
        // 使用 Spring 的工厂
        ApplicationContext applicationContext = new
                ClassPathXmlApplicationContext("spring.xml");
        // 通过工厂获得类:
        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.hello();

    }


}

2.3 IOC技术总结

  • ​ApplicationContext接口​​:工厂的接口,用于获取具体的Bean对象。常用的实现类有ClassPathXmlApplicationContextFileSystemXmlApplicationContext

  • ​Bean管理​​:通过idclassscope等属性配置Bean对象。

  • ​Bean对象的创建和销毁​​:通过init-methoddestroy-method属性配置Bean的生命周期方法。

2.4 实例化Bean对象的三种方式

1. ​​默认无参数构造方法​

<bean id="us" class="com.qcby.service.UserServiceImpl"/>

2. 静态工厂实例化方式

public class StaticFactory {
    public static UserService createUs() {
        System.out.println("通过静态工厂的方式创建 UserServiceImpl 对
象...");
        return new UserServiceImpl();
    }
}
<bean id="us" class="com.qcby.demo1.StaticFactory" factory-method="createUs"/>

3. 实例工厂实例化方式​

public class Dfactory {
    public UserService createUs() {
        System.out.println("实例化工厂的方式...");
        return new UserServiceImpl();
    }
}
<bean id="dfactory" class="com.qcby.demo1.Dfactory" />
<bean id="us" factory-bean="dfactory" factory-method="createUs" />

三、DI依赖注入

3.1 依赖注入的概述

        DI(Dependency Injection,依赖注入)是Spring框架负责创建Bean对象时,动态地将依赖对象注入到Bean组件中的过程。

3.2 DI的两种方式

1. Setter方法注入

//OrderDao
package com.qcby.dao;

public interface OrderDao {
    public void saveOrder();
}


//OrderDaoImpl
package com.qcby.dao;

public class OrderDaoImpl implements OrderDao{
    public void saveOrder() {
        System.out.println("持久层:保存订单...");
    }
}


//OrderService
package com.qcby.service;

public interface OrderService {
    public void saveOrder();
}


//OrderServiceImpl
package com.qcby.service;

import com.qcby.dao.OrderDao;

public class OrderServiceImpl implements OrderService{
    //编写成员属性,一定需要提供该属性的 set 方法
    private OrderDao orderDao;
    //一定需要提供该属性的 set 方法,IOC 容器底层就通过属性的 set 方法方式注入值
    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }
    //消息
    private String msg;
    //年龄
    private int age;
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void saveOrder() {
        System.out.println("业务层:保存订单..."+msg+" - "+age);
        //调用
        orderDao.saveOrder();
    }
}
    <!--DI:依赖注入-->
    <bean id="os" class="com.qcby.service.OrderServiceImpl">
        <property name="orderDao" ref="od" />
        <property name="msg" value="你好" />
        <property name="age" value="30" />
    </bean>
    <bean id="od" class="com.qcby.dao.OrderDaoImpl"></bean>
import com.qcby.service.OrderService;
import com.qcby.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo1 {

    @Test
    public void run3(){
        ApplicationContext applicationContext = new
                ClassPathXmlApplicationContext("spring.xml");
        OrderService orderService = (OrderService)applicationContext.getBean("os");
        orderService.saveOrder(); //业务层:保存订单...你好 - 30  持久层:保存订单...
    }

}

2. 构造器注入

package com.qcby.demo2;

public class Car {
    // 名称
    private String cname;
    // 金额
    private Double money;
    public Car(String cname, Double money) {
        this.cname = cname;
        this.money = money;
    }

    @Override
    public String toString() {
        return "Car{" +
                "cname='" + cname + '\'' +
                ", money=" + money +
                '}';
    }
}
    <!-- 属性构造方法方式注入值 -->
    <bean id="car" class="com.qcby.demo2.Car">
        <constructor-arg name="cname" value="大奔" />
        <constructor-arg name="money" value="400000" />
    </bean>
    @Test
    public void run4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Car car = (Car) context.getBean("car");
        System.out.println(car); //Car{cname='大奔', money=400000.0}
    }

3.3 复杂类型注入(数组,集合,Properties

package com.qcby.demo3;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class CollectionBean {
    // 数组
    private String [] strs;
    public void setStrs(String[] strs) {
        this.strs = strs;
    }
    private List<String> list;
    public void setList(List<String> list) {
        this.list = list;
    }
    private Map<String,String> map;
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "strs=" + Arrays.toString(strs) +
                ", list=" + list +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}
    <!--给集合属性注入值-->
    <bean id="collectionBean" class="com.qcby.demo3.CollectionBean">
        <property name="strs">
            <array>
                <value>美美</value>
                <value>小凤</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>熊大</value>
                <value>熊二</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="aaa" value="老王"/>
                <entry key="bbb" value="小王"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
    @Test
    public void run5(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        CollectionBean collectionBean = (CollectionBean) context.getBean("collectionBean");
        System.out.println(collectionBean);
        //CollectionBean{strs=[美美, 小凤], list=[熊大, 熊二], map={aaa=老王, bbb=小王}, properties={password=123456, username=root}}
    }

四、多配置文件管理

通过<import>标签加载多个配置文件实现模块化配置:

<!-- 在主配置文件中配置 -->
<import resource="applicationContext2.xml" />
ApplicationContext context = new ClassPathXmlApplicationContext(
    "applicationContext.xml", "applicationContext2.xml"
);

五、Spring框架开发程序的方式

Spring框架开发方式:

以下是一个使用Spring框架开发程序的完整示例:

1. 创建Maven工程,导入开发的jar包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qcby</groupId>
    <artifactId>spring02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql 驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    </dependencies>

</project>

2. 创建数据库,创建表结构

create database spring_db;
use spring_db;
create table account(
id int primary key auto_increment,
name varchar(40),
money double
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);

3. 编写JavaBean的类

package com.qcby.domain;

import java.io.Serializable;

public class Account implements Serializable{
    private static final long serialVersionUID = 7355810572012650248L;

    private Integer id;
    private String name;
    private Double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

4. 编写AccountDao的接口和实现类

package com.qcby.dao;

import com.qcby.domain.Account;

import java.util.List;

public interface AccountDao {
    public List<Account> findAll();
}
package com.qcby.dao;

import com.alibaba.druid.pool.DruidDataSource;
import com.qcby.domain.Account;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class AccountDaoImpl implements AccountDao{
    // 注入连接池对象
    private DataSource dataSource;
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    /**
     * 查询所有的数据
     * @return
     */
    public List<Account> findAll() {
        /*
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_db");
        dataSource.setUsername("root");
        dataSource.setPassword("12345");
        */

        List<Account> list=new ArrayList<Account>();
        Connection connection = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            // 获取连接
            connection = dataSource.getConnection();
            // 编写 sql 语句
            String sql = "select * from account";
            // 预编译
            stmt = connection.prepareStatement(sql);
            // 查询
            rs = stmt.executeQuery();
            // 遍历,封装数据
            while (rs.next()){
                Account account = new Account();
                account.setId(rs.getInt("id"));
                account.setName(rs.getString("name"));
                account.setMoney(rs.getDouble("money"));
                list.add(account);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
}

5. 编写AccountService的接口和实现类

package com.qcby.service;

import com.qcby.domain.Account;

import java.util.List;

public interface AccountService {
    public List<Account> findAll();
}
package com.qcby.service;

import com.qcby.dao.AccountDao;
import com.qcby.domain.Account;

import java.util.List;

public class AccountServiceImpl implements AccountService{
    // 依赖注入
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    /**
     * 查询所有的数据
     * @return
     */
    public List<Account> findAll() {
        return accountDao.findAll();
    }
}

6. 编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_db" />
        <property name="username" value="root" />
        <property name="password" value="12345" />
    </bean>
    <!--管理 bean-->
    <bean id="accountService" class="com.qcby.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao" />
    </bean>
    <bean id="accountDao" class="com.qcby.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

7. 编程测试程序

import com.qcby.domain.Account;
import com.qcby.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class Demo1 {
    @Test
    public void run1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        AccountService accountService = (AccountService) ac.getBean("accountService");
        // 调用方法
        List<Account> list = accountService.findAll();
        for (Account account : list) {
            System.out.println(account);
        }
    }
}

六、IOC注解开发

6.1 半注解方式(XML + 注解)

1. 核心思想

        在XML配置文件中开启注解扫描,结合代码中的注解(如@Component@Autowired)管理Bean,部分配置仍依赖XML文件。

2. 实现步骤

  1. 开启注解扫描:在XML中配置<context:component-scan>,指定扫描的包路径。

    <beans xmlns:context="http://www.springframework.org/schema/context">
        <context:component-scan base-package="com.qcby"/>
    </beans>
  2. 定义Bean:在类上使用@Component及其衍生注解(@Service@Repository@Controller)。

    @Service("userService")
    public class UserServiceImpl implements UserService {
        // ...
    }
  3. 依赖注入

    • 普通类型:使用@Value注入。

      @Value("Hello")
      private String message;
    • 引用类型:使用@Autowired按类型注入,或@Qualifier按名称注入。

      @Autowired
      @Qualifier("userDao")
      private UserDao userDao;

3. 常用注解

注解 作用
@Component 通用Bean注解,标识类为Spring管理的组件。
@Service 标识业务层组件。
@Repository 标识持久层组件(自动处理DAO层异常)。
@Autowired 按类型自动注入依赖(默认按类型,可配合@Qualifier按名称)。
@Scope 定义Bean作用域(如singletonprototype)。
@PostConstruct 初始化方法注解,等同于init-method
@PreDestroy 销毁方法注解,等同于destroy-method

4. 示例

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;

    @Value("1000")
    private int initialBalance;
}

6.2 纯注解方式(零XML)

1. 核心思想

        完全通过Java配置类(@Configuration)和注解替代XML文件,实现全注解驱动的开发。

2. 实现步骤

  1. 定义配置类:使用@Configuration标识配置类,@ComponentScan指定扫描包路径。

    @Configuration
    @ComponentScan("com.qcby")
    public class SpringConfig {
    
    }
  2. 注册Bean

    • 自动扫描:通过@ComponentScan自动注册标记了@Component的类。

    • 手动注册:在配置类中使用@Bean方法显式定义Bean。

      @Bean
      public DataSource dataSource() {
          DruidDataSource ds = new DruidDataSource();
          ds.setUrl("jdbc:mysql:///spring_db");
          return ds;
      }
  3. 加载配置类:通过AnnotationConfigApplicationContext加载配置类。

    ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

3. 常用注解

注解

作用

@Configuration

标识当前类为配置类,替代XML文件。

@ComponentScan

指定扫描包路径,自动注册Bean。

@Bean

在方法上定义Bean,方法返回值作为Bean实例(常用于第三方库的集成)。

@Import

引入其他配置类,实现模块化配置。

@PropertySource

加载外部配置文件(如.properties)。

4. 示例

@Configuration
@ComponentScan("com.qcby.demo4")
@Import(DataSourceConfig.class)
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql:///spring_db");
        return ds;
    }
}

6.3 对比分析

特性

半注解方式

纯注解方式

配置文件

需要XML文件(开启扫描)

完全无需XML,使用Java配置类

灵活性

适合遗留项目迁移或部分注解改造

适合新项目,完全面向注解开发

代码侵入性

较低(仅需少量注解)

较高(需编写配置类)

典型场景

逐步替换XML中的Bean定义

微服务、Spring Boot项目

依赖注入

支持@Autowired和XML混合配置

完全通过注解实现

七、Spring 框架整合 JUnit 单元测

        在传统的单元测试中,每次测试都需要手动创建Spring容器、加载配置文件,这不仅增加了代码量,还降低了测试效率。Spring框架针对这一问题提供了整合JUnit的解决方案,使得单元测试更加简洁高效。

7.1 基于XML配置的Spring整合JUnit测试

1. 环境准备

首先确保项目中已导入JUnit和Spring-test依赖:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
    <scope>test</scope>
</dependency>

2. 编写类和方法,把该类交给 IOC 容器进行管理

package com.qcby.demo5;

public class User {
    public void sayHello() {
        System.out.println("Hello....");
    }
}

3. 编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--整合单元测试-->
    <bean id="user" class="com.qcby.demo5.User"/>
</beans>

4. 编写测试类

package com.qcby.test;

import com.qcby.demo5.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Spring整合JUnit单元测试(XML配置方式)
 */
@RunWith(SpringJUnit4ClassRunner.class) // 使用Spring的测试运行器
@ContextConfiguration(value = "classpath:spring.xml") // 加载Spring配置文件
public class Demo5 {
    
    @Autowired // 自动注入User对象
    private User user;
    
    @Test
    public void run1() {
        user.sayHello(); // 调用被测试方法
    }
}

关键点说明:​​

  • @RunWith(SpringJUnit4ClassRunner.class):指定使用Spring的测试运行器

  • @ContextConfiguration:指定Spring配置文件位置

  • @Autowired:自动注入被测试对象

7.2 纯注解方式的Spring整合JUnit测试

1. 编写类和方法

package com.qcby.demo6;

import org.springframework.stereotype.Component;

@Component
public class Customer {
    public void save() {
        System.out.println("保存客户...");
    }
}

2. 编写配置类

package com.qcby.demo6;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Spring配置类(替代XML配置)
 */
//声明
@Configuration
@ComponentScan(value = "com.qcby.demo6") // 扫描指定包下的组件
public class SpringConfig6 {
}

3. 编写测试类

package com.qcby.test;

import com.qcby.demo6.Customer;
import com.qcby.demo6.SpringConfig6;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Spring整合JUnit单元测试(纯注解方式)
 */
@RunWith(SpringJUnit4ClassRunner.class)
//加载配置类
@ContextConfiguration(classes = SpringConfig6.class) // 指定配置类
public class Demo6 {
    
    //按类型注入
    @Autowired
    private Customer customer;
    
    @Test
    public void run1() {
        customer.save(); // 调用被测试方法
    }
}

关键点说明:​​

  • 使用@Configuration@ComponentScan替代XML配置

  • @ContextConfiguration(classes = ...)指定配置类

  • 其余部分与XML方式类似

7.3 对比分析

特性 XML配置方式 纯注解方式
配置方式 使用XML文件 使用Java配置类
灵活性 较低,修改需修改XML文件 较高,可直接修改Java代码
可读性 结构清晰,适合复杂配置 简洁,适合简单配置
维护性 配置分散,维护成本较高 配置集中,维护成本较低
适用场景 大型项目,需要精细控制Bean创建 中小型项目,快速开发和迭代

总结

        Spring框架通过IOC和AOP机制,彻底改变了Java企业级开发的方式。无论是基础的Bean管理,还是复杂的多数据源配置,Spring都提供了优雅的解决方案。掌握这些核心技术与高级特性,不仅能提升代码质量,还能大幅提高开发效率。在实际项目中,建议结合Spring Boot进一步简化配置,快速构建微服务应用。


网站公告

今日签到

点亮在社区的每一天
去签到