Spring上(IOC)笔记

1. Spring简介

1.1 Spring是什么

Spring是分层的JavaSE/EE全栈轻量级开源框架,

核心两大模块:IOC、AOP

作用:解耦、简化开发、方便整合其他框架(MyBatis、Redis等)

1.2 Spring框架的优点

  1. 方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。
  2. AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)
  3. 声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。
  4. 方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。

6.降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

1.3 IOC 控制反转 Inversion of Control

  • 传统方式:程序员自己new 对象,对象的创建控制权在程序员手里
  • IOC:对象的创建、管理、销毁交给Spring容器,控制权反转给框架
  • 容器:ApplicationContext(核心容器接口)
    • ClassPathXmlApplicationContext:加载类路径下xml
    • FileSystemXmlApplicationContext:加载磁盘绝对路径xml
  • Bean:Spring容器管理的对象,统称为Bean
  • 好处:降低耦合度,不需要自己new对象

1.3 DI 依赖注入 Dependency Injection

DI是IOC的实现手段:容器在创建Bean的时候,自动给Bean里面的成员变量赋值(注入依赖对象)

IOC是思想,DI是实现


2. Bean三种实例化方式

目标:告诉Spring怎么创建Bean对象

1.无参构造实例化(最常用)

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

Spring反射调用目标类无参构造创建对象;必须有无参构造。

2.静态工厂实例化

<bean id ="us2" class ="com.qcby.demo1.StaticFactory" factory-method ="createUs"></bean>

class写工厂类,factory-method 指定静态方法;直接调用静态方法返回Bean,不用创建工厂对象。

package com.qcby.demo1;

import com.qcby.service.UserService ;
import com.qcby.service.serviceImpl.UserServiceImpl;

public class StaticFactory {
public static UserService createUs(){
System.out .println("通过静态工厂的方式创建UserServiceImpl对象...");
return new UserServiceImpl();
}
}

3.实例工厂(动态工厂)

<bean id ="dfactory" class ="com.qcby.demo1.Dfactory" />
<bean id ="us3" factory-bean ="dfactory" factory-method ="createUs" />

先把工厂注册成Bean,factory-bean引用工厂id,调用工厂非静态方法生成目标对象。

package com.qcby.demo1;

import com.qcby.service.UserService ;
import com.qcby.service.serviceImpl.UserServiceImpl;

public class Dfactory {
// 普通成员方法(非 static ),必须先有工厂实例才能调用
public UserService createUs(){
System.out .println("实例化工厂的方式...");
return new UserServiceImpl();
}
}

方式 是否 static 特点
无参构造 - 日常开发首选
静态工厂 ✅ static 适配第三方静态工厂
实例工厂 ❌ 非 static 工厂有成员属性、状态

易错点:工厂内部new目标对象,仍然依赖目标类的无参构造!


3. Spring框架的Bean管理的配置文件方式

id属性,Bean起个名字,在约束中采用ID的约束,唯一,取值要求:必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号 id:不能出现特殊字符。

class属性,Bean对象的全路径。

scope属性,scope属性代表Bean的作用范围。

singleton单例(默认值),最常用的方式。

prototype多例

request应用在Web项目中,每次HTTP请求都会创建一个新的Bean

session应用在Web项目中,同一个HTTP Session 共享一个Bean

Bean对象的创建和销毁的两个属性配置

说明:Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法

init-method,当bean被载入到容器的时候调用init-method属性指定的方法

destroy-method,当bean从容器中删除的时候调用destroy-method属性指定的方法

单例的对象销毁:跟着容器工厂关闭才销毁

多例的对象销毁:垃圾回收机制进行回收的

考点: singleton:容器启动就创建;prototype:调用getBean才创建


4. Bean生命周期 ⭐

完整流程(xml方式)

  1. 实例化(调用无参构造)
  2. 属性赋值(DI依赖注入)
  3. 初始化(init-method 指定初始化方法)
  4. 对象正常使用
  5. 销毁(destroy-method 指定销毁方法,容器关闭时执行,单例才会销毁,多例不会由容器销毁)

xml配置:

<bean id="us1" class="xxx" init-method="init" destroy-method="destroy"/>

口诀:构造 → 赋值 → 初始化 → 使用 → 销毁


5. DI依赖注入

给Bean里面成员变量赋值,两种主流方式:set注入、构造注入

前提:类里面要有对应的set方法 / 构造方法

5.1 Set注入(最常用)

package com.qcby.service;

public interface OrderService {
public void saveOrder();
}

package com.qcby.service.serviceImpl;

import com.qcby.dao.OrderDao ;
import com.qcby.service.OrderService ;

public class OrderServiceImpl implements OrderService {

private OrderDao orderDao;
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();
}
}

package com.qcby.dao;

public interface OrderDao {
void saveOrder();
}

package com.qcby.dao.daoImpl;

import com.qcby.dao.OrderDao ;

public class OrderDaoImpl implements OrderDao {

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

<!--DI :依赖注入 -->
<bean id ="os" class ="com.qcby.service.serviceImpl.OrderServiceImpl">
<!-- 引用类型, ref 指向另一个 bean 的 id od --> <property name ="orderDao" ref ="od" />
<!-- 简单类型, value 赋值 --> <property name ="msg" value ="你好" />
<property name ="age" value ="30" />
</bean>
<!-- dao 层 bean , id=od -->
<bean id ="od" class ="com.qcby.dao.daoImpl.OrderDaoImpl"></bean>

5.2 构造注入(带参数构造)

package com.qcby.demo2;

public class Car {
// 名称
private String cname;
// 金额
private Double money;

复制代码
publicCar() {

}

// 带参数构造方法
public Car(String cname, Double money) {
this .cname = cname;
this .money = money;
}

@Override
publicString 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>


5.3. 数组,集合(List,Set,Map),Properties等的注入

package com.qcby.demo3;

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

public class CollectionBean {
// 1. 字符串数组
private String \[\] strs;
public void setStrs(String\[\] strs) {
this .strs = strs;
}

// 2.List 集合
private List <String> list;
public void setList(List <String> list) {
this .list = list;
}

// 3.Map 集合(键值对)
private Map <String,String> map;
public void setMap(Map <String, String> map) {
this .map = map;
}

// 4.Properties ,专门存字符串格式的配置(比如账号密码)
private Properties properties;
public void setProperties(Properties properties) {
this .properties = properties;
}

// toString :打印对象的时候,直接看到里面集合内容,方便测试
@Override
publicString toString() {
return "CollectionBean{" +
"strs=" + Arrays.toString (strs) +
", list=" + list +
", map=" + map +
", properties=" + properties +
'}';
}
}

<bean id ="collectionBean" class ="com.qcby.demo3.CollectionBean">
<!-- 给数组 strs 赋值 --> <property name ="strs">
<array>
<value>美美</value>
<value>小凤</value>
</array>
</property>

<!-- 给 list 赋值 --> <property name ="list">
<list>
<value>熊大</value>
<value>熊二</value>
</list>
</property>

<!-- 给 map 赋值, entry 就是一条键值对 --> <property name ="map">
<map>
<entry key ="aaa" value ="老王"/>
<entry key ="bbb" value ="小王"/>
</map>
</property>

<!-- Properties 配置 --> <property name ="properties">
<props>
<prop key ="username">root</prop>
<prop key ="password">123456</prop>
</props>
</property>
</bean>

5.4. 多配置文件方式

在src的目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种!

主配置文件中包含其他的配置文件:
<import resource="applicationContext2.xml"/>

工厂创建的时候直接加载多个配置文件:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml","applicationContext2.xml");

**6.**Spring框架开发程序的方式

6.1 Spring框架开发方式

  1. 需求:编写service和dao的类,演示代码

  2. 技术选择:持久层使用原始的JDBC的程序,连接池选择的是Druid连接池。创建maven工程,导入开发的jar包

  3. <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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.qcby</groupId>
    <artifactId>springdemo</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>springdemo Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <dependencies>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.20</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>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
    </dependency>
    <!-- mysql 驱动 --> <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
    </dependency>
    </dependencies>
    <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <build>
    <finalName>springdemo</finalName>
    </build>
    </project>

创建数据库,创建表结构

复制代码
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);

编写JavaBean的类

复制代码
packagecom.qcby.entity;



importjava.io.Serializable;



public classAccount implementsSerializable{



    private static final long*serialVersionUID*= 7355810572012650248L;



    privateInteger id;

    privateString name;

    privateDouble money;



    publicInteger getId() {

        returnid;

    }

    public voidsetId(Integer id) {

        this.id = id;

    }

    publicString getName() {

        returnname;

    }

    public voidsetName(String name) {

        this.name = name;

    }

    publicDouble getMoney() {

        returnmoney;

    }

    public voidsetMoney(Double money) {

        this.money = money;

    }



    @Override

    publicString toString() {

        return"Account{" +

                "id=" + id +

                ", name='" + name + '\'' +

                ", money=" + money +

                '}';

    }

}

编写AccountDao的接口和实现类

复制代码
packagecom.qcby.dao;



public interfaceOrderDao{

    voidsaveOrder();

}
复制代码
packagecom.qcby.dao.daoImpl;



importcom.qcby.dao.OrderDao;



public classOrderDaoImpl implementsOrderDao{



    public voidsaveOrder() {

        System.*out*.println("持久层:保存订单...");

    }

}
复制代码
packagecom.qcby.service;



importcom.qcby.entity.Account;



importjava.util.List;



public interfaceAccountService{

    publicList<Account> findAll();

}
复制代码
packagecom.qcby.service.serviceImpl;



importcom.qcby.dao.AccountDao;

importcom.qcby.entity.Account;

importcom.qcby.service.AccountService;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.stereotype.Component;



importjava.sql.Connection;

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

importjava.util.ArrayList;

importjava.util.List;

@Component("accountService")

public classAccountServiceImpl implementsAccountService{

    //依赖注入
privateAccountDaoaccountDao;

    public voidsetAccountDao(AccountDaoaccountDao) {

        this.accountDao = accountDao;

    }





    /\*\* \*查询所有的数据
\**@return*\*/publicList<Account> findAll() {

        returnaccountDao.findAll();

    }

}

编写配置文件

复制代码
<?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"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

         http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />

        <property name="url" value="jdbc:mysql:///spring_db?useSSL=false&amp;serverTimezone=Asia/Shanghai" />

        <property name="username" value="root" />

        <property name="password" value="980802" />

    </bean>

    <bean id="accountDao" class="com.qcby.dao.daoImpl.AccountDaoImpl">

        <property name="dataSource" ref="dataSource" />

    </bean>

    <bean id="accountService" class="com.qcby.service.serviceImpl.AccountServiceImpl">

        <property name="accountDao" ref="accountDao" />

    </bean>

</beans>

编程测试程序

复制代码
@Test

public voidrun3(){

    ApplicationContextac=newClassPathXmlApplicationContext("applicationContext.xml");

    AccountServiceaccountService = (AccountService) ac.getBean("accountService");

    List<Account> list = accountService.findAll();

    for(Account account : list) {

        System.*out*.println(account);

    }

}

7. IOC注解的方式

7.1. IOC注解方式的快速入门

IOC注解的方式依赖没有变化

编写接口和实现类

package com.qcby.service;

public interface UserService {

public void hello();

}

package com.qcby.service.serviceImpl;

import com.qcby.service.UserService ;

importorg.springframework.stereotype.Component;

//相当于<bean id="us"class="com.qcby.service.serviceImpl.UserServiceImpl" />

@Component(value = "us")

public class UserServiceImpl implements UserService {

@Override

public void hello() {

System.out .println("Hello IOC注解...");

}

}

编写配置文件,重点是开启注解扫描。

<?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" 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">

​

<!-- 扫描com.qcby下所有子包
entity实体类一般不加@Component,不需要交给Spring管理 -->
<context:component-scan base-package="com.qcby" />

​

</beans>

编写测试方法

@Test

public void run2(){

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

UserService userService = (UserService ) ac.getBean("us");

userService.hello();

}

7.2常用的注解

bean管理类常用的4个注解(作用相同,推荐使用在不同分层上)

​**@Component** 普通的类

​ @Controller 表现层

​ @Service 业务层

​**@Repository** 持久层

依赖注入常用的注解

​**@Value** 用于注入普通类型(String,int,double等类型)

​**@Autowired** 默认按类型进行自动装配(引用类型)

​ @Qualifier 和**@Autowired**一起使用,强制使用名称注入

​ @ResourceJava提供的注解,也被支持。使用name属性,按名称注入

对象生命周期(作用范围)注解

​ @Scope 生命周期注解,取值singleton(默认值,单实例)和prototype(多例)

初始化方法和销毁方法注解(了解)

​**@PostConstruct** 相当于init-method

​ @PreDestroy 相当于destroy-method

单例的销毁时机是跟随容器的 容器销毁对象销毁

多例的销毁时机是java的垃圾回收机制控制的

@Service("userService") //括号内就是bean的id,不写默认首字母小写类名

public class UserServiceImpl implements UserService{}

7.3 IOC纯注解的方式

纯注解的方式是微服务架构开发的主要方式,所以也是非常的重要。纯注解的目的是替换掉所有的配置文件。但是需要编写配置类。

编写配置类,替换掉applicationContext.xml配置文件

package com.qcby.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource ;

/**
* Spring**注解配置类,替代传统的
spring.xml 配置文件
*/
@Configuration *//*标识当前类是 Spring 的配置类
@ComponentScan("com.qcby") *//*组件扫描:扫描 com.qcby 包及其子包下带 @Component 等注解的类,交给 IOC 容器管理
public class SpringConfig {

/**
*注册 Druid 数据源 Bean ,交给 Spring IOC 容器
* @return 数据源对象
*/ @Bean("dataSource") //将方法返回对象存入 IOC 容器, bean 名称为 dataSource
public DataSource
createDataSource() {
*//创建 Druid 连接池对象
DruidDataSource dataSource = new DruidDataSource();
//设置 mysql 驱动类( mysql8 使用 cj 包下的驱动)
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
// url
:连接数据库地址

// spring_db :数据库名; serverTimezone 时区; useSSL 关闭 ssl ; allowPublicKeyRetrieval 解决公钥报错
dataSource.setUrl("jdbc:mysql:///spring_db?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true");
*// mysql
用户名

dataSource.setUsername("root");
*// mysql
*密码

dataSource.setPassword("980802");
return dataSource;
}
}

测试方法的编写

@Test
public void run3(){
ApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class );
AccountService accountService = (AccountService ) ac.getBean("accountService");
List <Account> list = accountService.findAll();
for (Account account : list) {
System.out .println(account);
}
}

常用的注解总结

@Configuration 声明是配置类

@ComponentScan 扫描具体包结构的

@Import注解 Spring的配置文件可以分成多个配置的,编写多个配置类。用于导入其他配置类

package com.qcbyjy.demo4;

import org.springframework.context.annotation.Configuration;

/**
* 新的配置类
*
*/
@Configuration // 声明配置类
public class SpringConfig2 {

}

// 声明当前类是配置类
@Configuration
// 扫描指定的包结构
@ComponentScan(value = "com.qcbyjy.demo4")
// @ComponentScan(value = {"com.qcbyjy.demo4","com.qcbyjy.demo3"})
// 引入新的配置类
@Import(value = {SpringConfig2.class})
public class SpringConfig {

@Bean注解 只能写在方法上,表明使用此方法创建一个对象,对象创建完成保存到IOC容器中

package com.qcbyjy.demo4;

import com.alibaba.druid.pool.DruidDataSource;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import javax.sql.DataSource;

/**

*

* Spring的配置类,替换掉applicationContext.xml

*

*/

// 声明当前类是配置类

@Configuration

// 扫描指定的包结构

@ComponentScan(value = "com.qcbyjy.demo4")

// @ComponentScan(value = {"com.qcbyjy.demo4","com.qcbyjy.demo3"})

// 引入新的配置类

@Import(value = {SpringConfig2.class})

public class SpringConfig {

/**

* 创建连接池对象,返回对象,把该方法创建后的对象存入到连接池中,使用@Bean注解解决

<!--配置连接池对象-->

<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="root" />

</bean>

*

* @return

*/

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

}

8. Spring框架整合JUnit单元测试

8.1 Spring框架整合JUnit单元测试

每次进行单元测试的时候,都需要编写创建工厂,加载配置文件等代码,比较繁琐。Spring提供了整合Junit单元测试的技术,可以简化测试开发。

必须先有Junit单元测试的环境,也就是说已经导入Junit单元测试的jar包。再导入spring-test的坐标依赖

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

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

package com.qcbyjy.demo5;

public class User {

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

}

编写配置文件applicationContext_test.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">

<!--整合单元测试-->
<bean id="user" class="com.qcbyjy.demo5.User"/>

</beans>

编写测试代码

package com.qcbyjy.test;

import com.qcbyjy.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单元测试
*
*/
@RunWith(value = SpringJUnit4ClassRunner.class) // 运行单元测试
@ContextConfiguration(value = "classpath:applicationContext_test.xml") // 加载类路径下的配置文件
public class Demo5 {

// 测试哪一个对象,把该对象注入进来,在测试环境下,可以使用注解的方式注入测试的对象
// 按类型自动注入
@Autowired
private User user;

@Test
public void run1(){
// 创建工厂,加载配置文件......
// 调用对象的方法
user.sayHello();
}

}

8.2 Spring整合单元测试(纯注解方式)

编写类和方法

复制代码
package com.qcbyjy.demo6;

​

import org.springframework.stereotype.Component;

​

@Component

public class Customer {

    

    public void save(){

        System.out.println("保存客户...");

    }

​

}

编写配置类
package com.qcbyjy.demo6;

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

/**
* Spring整合Junit配置类
*/
// 声明
@Configuration
// 扫描包结构
@ComponentScan(value = "com.qcbyjy.demo6")
public class SpringConfig6 {
}

编写测试方法

package com.qcbyjy.test;

import com.qcbyjy.demo6.Customer;

import com.qcbyjy.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();
}

}

相关推荐
荣码1 小时前
长上下文与大文档处理:200页PDF怎么喂给AI,我踩了4个坑
java·python
极限挑战哥2 小时前
共享电单车联营平台分账架构实践:二清合规与自动分账零人工方案
java·大数据·人工智能·微信小程序·架构·微信公众平台
皮皮林5512 小时前
比 VMware 更快,更轻的虚拟机,横空出世!
java
Thomas.Sir2 小时前
第13课:MyBatis-Plus整合SpringBoot4.x,分页、条件查询、逻辑删除实战
java·spring boot
meiying88383 小时前
多快递公司快递单号批量查询接口怎么对接?Python 聚合查询实现
java·大数据·python
小李不想当小白3 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
古法安卓3 小时前
Android-GPU压测工具
android·java·android studio
SL_staff3 小时前
10人团队如何用轻量私有化文档平台实现知识复用提效?技术视角拆解B/S架构下的协作闭环
java·开源·全栈
释厄6234 小时前
同性线套娃律——圆面积必然=1+2+...+n 的求和·圆心不与 π 相关
java·人工智能·算法·1024程序员节