整合Spring(一) —— 零xml配置让一个Maven项目用上Spring容器

前言

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。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值