介绍
Spring是一个开源框架,目的是简化Java开发,具备两大核心特性: 依赖注入(dependency injection, DI)和切面编程(aspect-oriented programming,AOP)。
依赖注入
依赖注入使得对象之间的耦合性降低, 基于Java中的反射机制实现。
Spring对于bean的装配提供了3种主要的装配机制:
- XML配置
- Java代码配置
- 自动发现和自动装配
3种机制可单独使用一种,也可配合使用。
本文暂先介绍Java代码配置和自动装配。
Java代码配置和自动装配
构造bean
为实现bean的装配,我们先实现一个bean,与普通类不同之处在于,用到@Component注解。如下示例是字符串的全半角转换。
package com.notepad.spring;
import org.springframework.stereotype.Component;
/**
* Description: 字符串处理函数
* <p>
* Create: 2018/6/17 18:55
*
* @author Yang Meng([email protected])
*/
@Component
public class StringProcess {
/**
* 字符串的全角转半角
*
* @param content 字符串
* @return 半角字符串
*/
public String stringQ2B(String content) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < content.length(); i++) {
int asciiCode = (int) content.charAt(i);
if (asciiCode >= 65281 && asciiCode <= 65374) {
asciiCode -= 65248;
} else if (asciiCode == 12288) {
asciiCode = 32;
}
stringBuilder.append((char) asciiCode);
}
return stringBuilder.toString();
}
/**
* 字符串半角转全角
*
* @param content 字符串
* @return 全角字符串
*/
public String stringB2Q(String content) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < content.length(); i++) {
int asciiCode = (int) content.charAt(i);
if (asciiCode >= 33 && asciiCode <= 126) {
asciiCode += 65248;
} else if (asciiCode == 32) {
asciiCode = 12288;
}
stringBuilder.append((char) asciiCode);
}
return stringBuilder.toString();
}
}
Java configure 类
利用Java代码实现bean的装配, 构造Java configure来整理需要用到的bean,用到注解 @Configuration和@Bean。
注:此处可配合使用@ComponentScan注解定位扫描位置。
package com.notepad.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: Spring Config配置(Java8)
* <p>
* Create: 2018/6/17 18:39
*
* @author Yang Meng([email protected])
*/
@Configuration
public class SpringConfig {
@Bean
public StringProcess getStringProcess() {
return new StringProcess();
}
}
bean装配验证
构造单测验证bean是否可以正常装配和使用。利用@RunWith和@ContextConfiguration来自动创建Spring上下文以及加载Java配置类,通过@Autowired注解实现bean的装配。
package com.notepad.spring;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* Description: Bean测试
* <p>
* Create: 2018/6/17 19:26
*
* @author Yang Meng([email protected])
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = StringProcess.class)
public class StringProcessTest {
@Autowired
private StringProcess stringProcess;
@Test
public void stringQ2B() {
String content = "2018年世界杯开幕了。";
System.out.println(stringProcess.stringQ2B(content));
}
@Test
public void stringB2Q() {
String content = "2018年世界杯。";
System.out.println(stringProcess.stringB2Q(content));
}
}
Main方法使用
利用SpringJUnit4ClassRunner可以完成单测, 但是如何Main方法中要使用该bean还需要用到AnnotationConfigApplicationContext来加载Spring上下文,示例如下:
package com.notepad.spring;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Description: Main方法中实用bean(Java8)
* <p>
* Create: 2018/6/17 23:14
*
* @author Yang Meng([email protected])
*/
public class SpringMain {
public static void main(String [] args) {
StringProcess process = getStringProcess();
if (process == null) {
LOG.error("Can not create bean: StringProcess");
return;
}
String content = "北京时间23点整。";
System.out.println(process.stringQ2B(content));
}
/**
* 通过上下文加载获取bean
*
* @return StringProcess
*/
private static StringProcess getStringProcess() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
return context.getBean(StringProcess.class);
}
private final static Logger LOG = LoggerFactory.getLogger(SpringMain.class);
}
总结
- @Component注解在普通类上声明bean
- @Configuration注解声明Java配置类, @Bean注解声明具体bean实现细节
- @RunWith和@ContextConfiguration注解使用单测
- AnnotationConfigApplicationContext实现Main方法中加载bean
后续问题
- Java配置类与XML配置相互配合
- Bean重名问题
- 类之外属性的注入
- 利用properties文件实现具体值注入等等
参考
- Spring 实战(第四版) 第二章, 第三章