前言
Springboot大行其道的当下,很少有人单独自己整合Spring进行开发了,但是发现Spring提供的容器配合注解开发是真的非常方便。
有些非web项目使用Springboot开发难免有些不伦不类,为了能够既享受Spring带来的方便,又不让非web项目开发起来不这么不伦不类,我做了一系列的尝试,将Spring生态中的组件逐一自己做了整合。
网上很多整合案例,但是不少是需要xml的,这个整合系列尽可能的抛弃了xml方式的整合,而采用注解方式整合。
今天是这个系列的第一篇,将Spring引入一个普普通通的maven项目。
pom文件
导入Spring所有依赖文件
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.version>5.3.6</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
打包插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<!--指定程序运行主类-->
<manifest>
<mainClass>it.aspirin.HelloApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<!--这一行在idea里面可能会报红,但是没有报错,而且这句才是关键,如果去掉这一句不会生成拥有全部依赖的jar包-->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
项目结构
项目结构如下
主要创建了启动类HelloApplication.java,几个测试依赖注入的类HelloController.java, ImageService.java,ClickhouseImageServiceImpl.java,MysqlImageServiceImpl.java,ImageContext.java。下面会讲到。
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── it
│ │ └── aspirin
│ │ ├── HelloApplication.java
│ │ ├── controller
│ │ │ └── HelloController.java
│ │ ├── mapper
│ │ │ └── ImageMapper.java
│ │ └── service
│ │ ├── ImageService.java
│ │ └── impl
│ │ ├── ClickhouseImageServiceImpl.java
│ │ ├── ImageContext.java
│ │ └── MysqlImageServiceImpl.java
│ └── resources
│ ├── application.properties
└── test
└── java
创建类
创建类添加注解
@Controller
public class HelloController {
@Value("${jdbc.driver}")
private String driver;
public String sayHello(String name) {
return driver + " hello " + name;
}
}
@Service
public class ClickhouseImageServiceImpl implements ImageService {
@Override
public String databaseType() {
return "ck";
}
@Override
public String insert() {
return "ck insert";
}
}
@Service
public class MysqlImageServiceImpl implements ImageService {
@Resource
ImageService imageService;
@Override
public String databaseType() {
return "mysql";
}
@Override
public String insert() {
return "mysql insert";
}
}
@Service
public class ImageContext implements ApplicationContextAware {
private final Map<String, ImageService> map = new ConcurrentHashMap<>();
public String insert(String databaseType) {
final ImageService imageService = Optional
.ofNullable(map.get(databaseType))
.orElseThrow(() -> new IllegalArgumentException("invalid database type:" + databaseType));
return imageService.insert();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
final Map<String, ImageService> tempMap = applicationContext.getBeansOfType(ImageService.class);
tempMap.values().forEach(service -> map.put(service.databaseType(), service));
}
}
启动类
启动类跟Springboot一样,主要添加包扫描注解ComponentScan,用法一样。
然后通过AnnotationConfigApplicationContext类获取创建的容器。比如下面获取了HelloController类的实例,这个类并没有通过new的方式实例化。
@ComponentScan("it.aspirin")
public class HelloApplication {
public static void main(String[] args) {
final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(HelloApplication.class);
final HelloController bean = context.getBean(HelloController.class);
final String info = bean.sayHello("aspirin");
LOGGER.info("info = {}", info);
final ImageContext imageContext = context.getBean(ImageContext.class);
LOGGER.info("imageContext.insert(\"mysql\") = " + imageContext.insert("mysql"));
}
}
总结
单纯集成Spring相对比较简单。只需要导入依赖,添加ComponentScan扫描类即可。
然后通过AnnotationConfigApplicationContext对象获取到需要的对象。
这样的好处是创建单例对象变得非常容易,对象实例不再需要手动管理,而是交给Spring统一进行管理。
日常工作操作数据库必不可少,因此下期文章讲解无xml配置纯注解方式spring集成mybatis。