Spring框架--IOC技術

一、Spring框架的介紹

1、Spring框架的概述

? ? Spring 是一個開放源代碼的設計層面框架,它解決的是業務邏輯層和其他各層的松耦合問題,因此它將面向接口的編程思想貫穿整個系統應用。Spring是于2003年興起的一個輕量級的Java開發框架,由 Rod Johnson 創建。簡單來說,Spring是一個分層的 JavaSE/EE full-stack(一站式) 輕量級開源框架。

? ? Spring 是于 2003 年興起的一個輕量級的 Java 開發框架,由 Rod Johnson 在其著作 Expert One-On-One J2EE Development and Design 中闡述的部分理念和原型衍生而來。它是為了解決企業應用開發的復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為 J2EE 應用程序開發提供集成的框架。

? ? Spring 的核心是控制反轉(IoC 控制反轉)和面向切面(AOP)。簡單來說,Spring 是一個分層的 JavaSE/EEfull-stack(一站式) 輕量級開源框架。

2、Spring框架的優點

  • 方便解耦,簡化開發,Spring 就是一個大工廠,可以將所有對象創建和依賴關系維護,交給 Spring 管理。IOC 的作用。
  • AOP 編程的支持,Spring 提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能。(可擴展性)
  • 聲明式事務的支持,只需要通過配置就可以完成對事務的管理,而無需手動編程。
  • 方便程序的測試,Spring Junit4 支持,可以通過注解方便的測試 Spring 序。
  • 方便集成各種優秀框架,Spring 不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts2HibernateMyBatisQuartz 等)的直接支持。
  • 降低 JavaEE API 的使用難度,Spring JavaEE 開發中非常難用的一些 API JDBCJavaMail、遠程調用等),都提供了封裝,使這些 API 應用難度大大降低。

二、Spring IOC 核心技術

1、什么是 IOC

IOC -- Inverse of Control,控制反轉,將對象的創建權力反轉給 Spring 框架

控制反轉(Inversion of Control,縮寫為 IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。

解決問題:使用 IOC 可以解決的程序耦合性高的問題,Spring 的工廠讀取配置文件。

2、IOC 的程序入門

創建 Java 工程,導入坐標依賴

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

編寫接口和實現類,編寫具體的實現方法

package com.qcbyjy.service;
public interface UserService {
public void hello();
}
package com.qcbyjy.service;
public class UserServiceImpl implements UserService {
@Override
public void hello() {
System.out.println("Hello IOC!!");
}
}

編寫 Spring 核心的配置文件,在 src 目錄下創建 applicationContext.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.qcbyjy.service.UserServiceImpl"
/>
</beans>

log4j.properties 的配置文件拷貝到 resources 目錄下,做為 log4j 的日志配置文件。編寫測試方法。

package com.qcbyjy.test;
import com.qcbyjy.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("applicationContext.xml");
// 通過工廠獲得類:
UserService userService = (UserService)
applicationContext.getBean("userService");
userService.hello();
}
}

3、IOC 技術總結

ApplicationContext 接口,工廠的接口,使用該接口可以獲取到具體的 Bean 對象。該接口下有兩個具體的實現類。?

ClassPathXmlApplicationContext,加載類路徑下的 Spring 配置文件。

FileSystemXmlApplicationContext,加載本地磁盤下的 Spring 配置文件。

4、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 屬性指定的方法

5、實例化 Bean 對象的三種方式

默認是無參數的構造方法(默認方式,基本上使用)

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

靜態工廠實例化方式

package com.qcbyjy.demo1;
import com.qcbyjy.service.UserService;
import com.qcbyjy.service.UserServiceImpl;
/**
* 靜態工廠方式
*/
public class StaticFactory {
// 靜態工廠方式
public static UserService createUs(){
System.out.println("通過靜態工廠的方式創建 UserServiceImpl 對
象...");
// 編寫很多業務邏輯 權限校驗
return new UserServiceImpl();
}
}
<bean id="us" class="com.qcbyjy.demo1.StaticFactory"
factory-method="createUs" />

實例工廠實例化方式

package com.qcbyjy.demo1;
import com.qcbyjy.service.UserService;
import com.qcbyjy.service.UserServiceImpl;
/**
*
* 動態工廠方式
*
*/
public class Dfactory {
public UserService createUs(){
System.out.println("實例化工廠的方式...");
return new UserServiceImpl();
}
}
<bean id="dfactory" class="com.qcbyjy.demo1.Dfactory" />
<bean id="us" factory-bean="dfactory" factory-method="createUs" />

三、DI 依賴注入

1、依賴注入的概述

IOC DI 的概念

  • IOCInverse of Control,控制反轉,將對象的創建權反轉給 Spring
  • DIDependency Injection,依賴注入,在 Spring 框架負責創建 Bean 對象時,動態的將依賴對象注入到 Bean 組件中!!

2、屬性的 set 方法注入值

編寫屬性,提供該屬性對應的 set 方法,編寫配置文件完成屬性值的注入

package com.qcbyjy.service;
import com.qcbyjy.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;
}
@Override
public void saveOrder() {
System.out.println("業務層:保存訂單..."+msg+" - "+age);
// 調用
orderDao.saveOrder();
}
}
package com.qcbyjy.dao;
public class OrderDaoImpl implements OrderDao {
@Override
public void saveOrder() {
System.out.println("持久層:保存訂單...");
}
}
<!--DI:依賴注入-->
<bean id="os" class="com.qcbyjy.service.OrderServiceImpl">
<property name="orderDao" ref="od" />
<property name="msg" value="你好" />
<property name="age" value="30" />
</bean>
<bean id="od" class="com.qcbyjy.dao.OrderDaoImpl"></bean>

3屬性構造方法方式注入值

對于類成員變量,構造函數注入。

package com.qcbyjy.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.qcbyjy.demo2.Car">
<constructor-arg name="cname" value="大奔" />
<constructor-arg name="money" value="400000" />
</bean>

4、數組,集合(List,Set,Map)Properties等的注入

package com.qcbyjy.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.qcbyjy.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>

四、多配置文件方式

1、多配置文件的加載方式

src 的目錄下又多創建了一個配置文件,現在是兩個核心的配置文件,那么加載這兩個配置文件的方式有兩種

主配置文件中包含其他的配置文件:
<import resource="applicationContext2.xml"/>
工廠創建的時候直接加載多個配置文件:
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");

五、Spring 框架開發程序的方式

1、Spring 框架開發方式

1. 需求:編寫 service dao 的類,演示代碼

2. 技術選擇:持久層使用原始的 JDBC 的程序,連接池選擇的是 Druid 連接池。創建 maven 工程,導入開發的 jar

<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.6</version>
</dependency>
</dependencies>

創建數據庫,創建表結構

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 的類

package com.qcbyjy.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 +
'}';
}
}

編寫 AccountDao 的接口和實現類

package com.qcbyjy.dao;
import com.qcbyjy.domain.Account;
import java.util.List;
public interface AccountDao {
public List<Account> findAll();
}
package com.qcbyjy.dao;
import com.qcbyjy.domain.Account;
import com.alibaba.druid.pool.DruidDataSource;
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
*/
@Override
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("root");
*/
List<Account> list = new ArrayList<>();
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;
}
}
package com.qcbyjy.service;
import com.qcbyjy.domain.Account;
import java.util.List;
public interface AccountService {
public List<Account> findAll();
}
package com.qcbyjy.service;
import com.qcbyjy.dao.AccountDao;
import com.qcbyjy.domain.Account;
import java.util.List;
public class AccountServiceImpl implements AccountService {
// 依賴注入
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 查詢所有的數據
* @return
*/
@Override
public List<Account> findAll() {
return accountDao.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"
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="root" />
</bean>
<!--管理 bean-->
<bean id="accountService"
class="com.qcbyjy.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao" />
</bean>
<bean id="accountDao" class="com.qcbyjy.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>

編程測試程序

package com.qcbyjy.test;
import com.qcbyjy.domain.Account;
import com.qcbyjy.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("applicationContext.xml");
AccountService accountService = (AccountService)
ac.getBean("accountService");
// 調用方法
List<Account> list = accountService.findAll();
for (Account account : list) {
System.out.println(account);
}
}
}

六、IOC 注解的方式

1、IOC注解方式的快速入門

IOC 注解的方式依賴沒有變化

編寫接口和實現類

package com.qcbyjy.demo2;
public interface UserService {
public void hello();
}
package com.qcbyjy.demo2;
import org.springframework.stereotype.Component;
/**
* <bean id="us" class="com.qcbyjy.demo2.UserServiceImpl" />
*/
// 組件,作用:把當前類使用 IOC 容器進行管理,如果沒有指定名稱,默認使用類名,
首字母是小寫。userServiceImpl。或者自己指定名稱
@Component(value = "us")
public class UserServiceImpl implements UserService {
@Override
public void hello() {
System.out.println("Hello IOC 注解...");
}
}

在需要管理的類上添加@Component 注解

@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">
<!--開啟注解掃描
<context:component-scan base-package="com.qcbyjy.demo2" />
-->
<!--開啟注解掃描 com.qcbyjy.所有的包中的所有的類 -->
<context:component-scan base-package="com.qcbyjy" />
</beans>

編寫測試方法

package com.qcbyjy.test;
import com.qcbyjy.demo2.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo2 {
/**
* IOC 注解方式的入門
*/
@Test
public void run1(){
// 工廠
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext_anno.xml");
// 獲取對象
UserService userService = (UserService) ac.getBean("us");
userService.hello();
}
}

1.6.2 2. 常用的注解

bean 管理類常用的 4 個注解(作用相同,推薦使用在不同分層上)

  • @Component 普通的類
  • @Controller 表現層@Service 業務層
  • @Repository 持久層

依賴注入常用的注解

  • @Value 用于注入普通類型(Stringintdouble 等類型)
  • @Autowired 默認按類型進行自動裝配(引用類型)
  • @Qualifier @Autowired 一起使用,強制使用名稱注入
  • @Resource Java 提供的注解,也被支持。使用 name 屬性,按名稱注入

對象生命周期(作用范圍)注解

  • @Scope 生命周期注解,取值 singleton(默認值,單實例)和 prototype(多

例)

初始化方法和銷毀方法注解(了解)

  • @PostConstruct 相當于 init-method
  • @PreDestroy 相當于 destroy-method

具體的代碼如下

package com.qcbyjy.demo3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
// 默認當前類名就是 ID 名稱,首字母小寫
@Component(value = "c")
// @Controller
// @Service(value = "c")
// @Repository(value = "c")
// @Scope(value = "singleton") // 默認值,單例的
// @Scope(value = "prototype") // 多例的
public class Car {
// 注解注入值,屬性 set 方法是可以省略不寫的。
// 只有一個屬性,屬性的名稱是 value,value 是可以省略不寫的
@Value("大奔 2")
private String cname;
@Value(value = "400000")
private Double money;
// 也不用提供 set 方法
// 按類型自動裝配的注解,和 id 名稱沒有關系
@Autowired
// 按 id 的名稱注入,Qualifier 不能單獨使用,需要 Autowired 一起使用。
// @Qualifier(value = "person")
// @Resource Java 提供的注解,按名稱注入對象,屬性名稱是 name
// @Resource(name = "person")
private Person person;
/**
* Car 對象創建完成后,調用 init 方法進行初始化操作
*/
@PostConstruct
public void init(){
System.out.println("操作...");
}
/*
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
*/
@Override
public String toString() {
return "Car{" +
"cname='" + cname + '\'' +
", money=" + money +
", person=" + person +
'}';
}
}
package com.qcbyjy.demo3;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "person")
public class Person {
@Value("張三")
private String pname;
@Override
public String toString() {
return "Person{" +
"pname='" + pname + '\'' +
'}';
}
}
package com.qcbyjy.test;
import com.qcbyjy.demo2.UserService;
import com.qcbyjy.demo3.Car;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo3 {
@Test
public void run1(){
// 工廠
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext_anno.xml");
// 獲取對象
Car car = (Car) ac.getBean("c");
System.out.println(car);
}
}

3、IOC 純注解的方式

純注解的方式是微服務架構開發的主要方式,所以也是非常的重要。純注解的目的是替換掉所有的配置文件。但是需要編寫配置類。

編寫實體類

package com.qcbyjy.demo4;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Order {
@Value("北京")
private String address;
@Override
public String toString() {
return "Order{" +
"address='" + address + '\'' +
'}';
}
}

編寫配置類,替換掉 applicationContext.xml 配置文件

package com.qcbyjy.demo4;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Spring 的配置類,替換掉 applicationContext.xml
*
*/
// 聲明當前類是配置類
@Configuration
// 掃描指定的包結構
@ComponentScan(value = "com.qcbyjy.demo4")
public class SpringConfig {
}

測試方法的編寫

package com.qcbyjy.test;
import com.qcbyjy.demo4.Order;
import com.qcbyjy.demo4.SpringConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationCo
ntext;
public class Demo4 {
/**
* 編寫程序,需要加載配置類
*/
@Test
public void run1(){
// 創建工廠,加載配置類
ApplicationContext ac = new
AnnotationConfigApplicationContext(SpringConfig.class);
// 獲取到對象
Order order = (Order) ac.getBean("order");
System.out.println(order);
}
}

常用的注解總結

  • @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;
}
}

七、Spring 框架整合 JUnit 單元測

1、Spring 框架整合 JUnit 單元測試

每次進行單元測試的時候,都需要編寫創建工廠,加載配置文件等代碼,比較繁瑣。Spring 提供了整合 Junit 單元測試的技術,可以簡化測試開發。下面開始學習該技術。

必須先有 Junit 單元測試的環境,也就是說已經導入 Junit 單元測試的 jar 包。咱們已經導入過了。使用的是 4.12 版本

再導入 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();
}
}

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82193.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82193.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82193.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flannel后端為UDP模式下,分析數據包的發送方式——tun設備(三)

在分析 Kubernetes 環境中 Flannel UDP 模式的數據包轉發時&#xff0c;我們提到 flannel.1 是一個 TUN 設備&#xff0c;它在數據包處理中起到了關鍵作用。 什么是 TUN 設備&#xff1f; TUN 設備&#xff08;Tunnel 設備&#xff09;是 Linux 系統中一種虛擬網絡接口&#x…

2025深圳國際無人機展深度解析:看點、廠商與創新亮點

2025深圳國際無人機展深度解析&#xff1a;看點、廠商與創新亮點 1.背景2.核心看點&#xff1a;技術突破與場景創新2.1 eVTOL&#xff08;飛行汽車&#xff09;的規模化展示2.2 智能無人機與無人值守平臺2.3 新材料與核心零部件革新2.4 動態演示與賽事活動 3.頭部無人機廠商4.核…

【Jitsi Meet】(騰訊會議的平替)Docker安裝Jitsi Meet指南-使用內網IP訪問

Docker安裝Jitsi Meet指南-使用內網IP訪問 下載官方代碼配置環境變量復制示例環境文件并修改配置&#xff1a;編輯 .env 文件&#xff1a; 修改 docker-compose.yml 文件生成自簽名證書啟動服務最終驗證 騰訊會議的平替。我們是每天開早晚會的&#xff0c;都是使用騰訊會議。騰…

使用Spring Boot和Spring Security結合JWT實現安全的RESTful API

使用Spring Boot和Spring Security結合JWT實現安全的RESTful API 引言 在現代Web應用中&#xff0c;安全性是至關重要的。Spring Boot和Spring Security提供了強大的工具來保護我們的應用程序&#xff0c;而JWT&#xff08;JSON Web Token&#xff09;則是一種輕量級的認證和…

對神經正切核的理解和推導(1)

聲明&#xff1a; 本文是對Neural Tangent Kernel &#xff08;NTK&#xff09;基礎推導 - Gearlesskai - 博客園文章內容的理解與推導&#xff0c;里面很多東西對我這種新手來說不太好理解&#xff0c;所以我力求通過這種方式理解文章的大部分內容。希望我的理解可以幫助你更…

基于 STC89C52 的養殖場智能溫控系統設計與實現

摘要 本文提出一種基于 STC89C52 單片機的養殖場環境溫度智能控制系統,通過集成高精度溫度傳感器、智能執行機構及人機交互模塊,實現對養殖環境的實時監測與自動調控。系統具備溫度閾值設定、超限報警及多模式控制功能,可有效提升養殖環境穩定性,降低能耗與人工成本。 一…

微信小程序調試

一、尋找答案 1. 創建小程序 https://zhuanlan.zhihu.com/p/1906013675883561860 2. 若有后端接口&#xff0c;需要調試 https://blog.csdn.net/animatecat/article/details/126949749 3. 比較細教程, 搭建修改配置 https://zhuanlan.zhihu.com/p/1893281527112136235 4. 查找…

使用DeepSeek實現數據處理

一、核心能力全景圖 Ctrl+/ 喚醒智能助手,支持以下數據處理場景: ?? 數據清洗與預處理?? 統計分析與可視化?? 機器學習建模?? 大數據性能優化?? 自動化報告生成? 實時流數據處理二、高頻場景實戰(附魔法口令) 場景1:數據清洗自動化(Python示例) 口令: 處…

符合Python風格的對象(使用 __slots__ 類屬性節省空間)

使用__slots__ 類屬性節省空間 默認情況下&#xff0c;Python 在各個實例中名為__dict__ 的字典里存儲實例屬 性。如 3.9.3 節所述&#xff0c;為了使用底層的散列表提升訪問速度&#xff0c;字典會消 耗大量內存。如果要處理數百萬個屬性不多的實例&#xff0c;通過__slots__…

民宿管理系統5

管理員管理&#xff1a; 新增管理員信息&#xff1a; 前端效果&#xff1a; 前端代碼&#xff1a; <body> <div class"layui-fluid"><div class"layui-row"><div class"layui-form"><div class"layui-form-i…

?騰訊地圖軌跡云:重構位置管理的數字神經中樞

——從軌跡追蹤到智能決策&#xff0c;開啟產業互聯網新篇章 在數字經濟與實體經濟深度融合的今天&#xff0c;位置服務已成為企業數字化轉型的核心基礎設施。無論是物流運輸中的車輛調度、共享經濟中的設備管理&#xff0c;還是智慧城市中的交通優化&#xff0c;精準的軌跡數…

rce命令執行原理及靶場實戰(詳細)

2. 原理 在根源上應用系統從設計上要給用戶提供一個指定的遠程命令操作的接口。漏洞主要出現在常見的路由器、防火墻、入侵檢測等設備的web管理界面上。在管理界面提供了一個ping服務。提交后&#xff0c;系統對該IP進行ping&#xff0c;并且返回結果。如果后臺服務器并沒有對…

GeoTools 將 Shp 導入PostGIS 空間數據庫

前言 ? GeoTools 在空間數據轉換處理方面具有強大的能力&#xff0c;能夠高效、簡潔的操縱 Shp 數據。特別是與空間數據庫PostGIS 相結合&#xff0c;更能展示出其空間數據處理的優勢&#xff0c;借助 GeoTools&#xff0c;我們可以實現 Shp 數據高效入庫。 本文上接系列文章 …

基于SpringBoot+Vue的家政服務系統源碼適配H5小程序APP

市場前景 隨著社會經濟的發展和人口老齡化的加劇&#xff0c;家政服務需求不斷增長。我國65歲及以上人口增長較快&#xff0c;2022年我國65歲及以上老年人數量達2.1億人&#xff0c;占比較2016年增長4.1個百分點&#xff0c;達14.9%。我國65歲及以上人口數量龐大&#xff0c;老…

《企業級日志該怎么打?Java日志規范、分層設計與埋點實踐》

大家好呀&#xff01;&#x1f44b; 今天我們要聊一個Java開發中超級重要但又經常被忽視的話題——日志系統&#xff01;&#x1f4dd; 不管你是剛入門的小白&#xff0c;還是工作多年的老司機&#xff0c;日志都是我們每天都要打交道的"好朋友"。那么&#xff0c;如…

1Panel vs 寶塔面板:現代化運維工具的全方位對比

1Panel vs 寶塔面板對比分析 1Panel 和 寶塔面板&#xff08;BT-Panel&#xff09;都是服務器管理工具&#xff0c;旨在簡化 Linux 服務器的運維工作&#xff0c;但它們在設計理念、功能側重點和技術實現上有明顯差異。以下從多個維度對兩者進行對比分析&#xff1a; 1. 定位與…

怎么開發一個網絡協議模塊(C語言框架)之(四) 信號量初始化

// 原始代碼 /* gVrrpInstance.sem = OsixCreateBSem(OSIX_SEM_Q_PRIORITY, OSIX_SEM_FULL); */ gVrrpInstance.sem = OsixCreateMSem(OSIX_SEM_Q_FIFO | OSIX_SEM_DELETE_SAFE); if (gVrrpInstance.sem == NULL) {printf("[VRRP]:vrrp init error, failed to create vrrp…

電腦C盤清理技巧:釋放空間,提升性能

文章目錄 一、使用系統自帶的磁盤清理工具&#xff08;一&#xff09;打開磁盤清理工具&#xff08;二&#xff09;清理臨時文件&#xff08;三&#xff09;清理系統文件 二、使用第三方清理工具&#xff08;一&#xff09;CCleaner&#xff08;極力推薦&#xff09;&#xff0…

ARM筆記-ARM處理器及系統結構

第二章 ARM處理器及系統結構 2.1 ARM處理器簡介 采用RISC架構的ARM微處理器的特點&#xff1a; 體積小、功耗低、低成本、高性能&#xff1b;支持 Thumb&#xff08;16位&#xff09;/ARM&#xff08;32位&#xff09;雙指令集&#xff0c;能很好地兼容 8位/16位 器件&#x…

關于如何在Springboot項目中通過excel批量導入數據

接口文檔 2.5 批量導入學生賬號 2.5.1 基本信息 請求路徑:/admin/students/batch-import 請求方式:POST 接口描述:通過上傳Excel文件批量導入學生賬號信息。 2.5.2 請求參數 參數格式:multipart/form-data 參數說明: 參數名稱參數類型是否必須備注filefile是包含學…