分类 Java 下的文章

安装条件

  • Maven需要本机安装Java环境、必须包含JAVA_HOME环境变量

安装步骤

  1. 从官网下载maven安装包,解压后放在D:\software\apache-maven-x.x.x目录;
  2. 添加MAVEN_HOME环境变量;修改path环境变量,新增%MAVEN_HOME%\bin;
    2025-02-10T09:34:30.png
  3. 命令行测试

    mvn -v 
    # 输出版本信息即可,如果错误,请仔细检查环境变量即可!
    # 友好提示,如果此处错误,绝大部分原因都是java_home变量的事,请仔细检查!!
  4. 修改配置文件
    主要有三个配置需要修改:1.本地仓库位置;2.添加国内镜像源;3.Maven默认编译项目的jdk版本
    4.1. 配置本地仓库位置

    <!-- conf/settings.xml 55行 -->
    <localRepository>D:\repository</localRepository>

    4.2. 添加国内镜像源

    <!--在mirrors节点(标签)下添加中央仓库镜像 160行附近-->
    <mirror>
     <id>alimaven</id>
     <name>aliyun maven</name>
     <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
     <mirrorOf>central</mirrorOf>
    </mirror>

    4.3. 配置jdk17版本项目构建

    <!--在profiles节点(标签)下添加jdk编译版本 268行附近-->
    <profile>
     <id>jdk-17</id>
     <activation>
       <activeByDefault>true</activeByDefault>
       <jdk>17</jdk>
     </activation>
     <properties>
       <maven.compiler.source>17</maven.compiler.source>
       <maven.compiler.target>17</maven.compiler.target>
       <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
     </properties>
    </profile>
  5. idea配置本地Maven

    idea工具默认自带Maven配置软件,但是因为没有修改配置,建议替换成本地配置好的maven!
    file -> settings -> build -> build tool -> maven

开发应用程序时,我们会使用开发环境,例如,使用内存数据库以便快速启动。而运行在生产环境时,我们会使用生产环境,例如,使用MySQL数据库。如果应用程序可以根据自身的环境做一些适配,无疑会更加灵活。

Spring为应用程序准备了Profile这一概念,用来表示不同的环境。例如,我们分别定义开发、测试和生产这3个环境:

  • native
  • test
  • production

创建某个Bean时,Spring容器可以根据注解@Profile来决定是否创建。例如,以下配置:

@Configuration
@ComponentScan
public class AppConfig {
    @Bean
    @Profile("!test")
    ZoneId createZoneId() {
        return ZoneId.systemDefault();
    }

    @Bean
    @Profile("test")
    ZoneId createZoneIdForTest() {
        return ZoneId.of("America/New_York");
    }
}

如果当前的Profile设置为test,则Spring容器会调用createZoneIdForTest()创建ZoneId,否则,调用createZoneId()创建ZoneId。注意到@Profile("!test")表示非test环境。

在运行程序时,加上JVM参数-Dspring.profiles.active=test就可以指定以test环境启动。

实际上,Spring允许指定多个Profile,例如:

-Dspring.profiles.active=test,master

可以表示test环境,并使用master分支代码。

要满足多个Profile条件,可以这样写:

@Bean
@Profile({ "test", "master" }) // 同时满足test和master
ZoneId createZoneId() {
    ...
}

使用Conditional

除了根据@Profile条件来决定是否创建某个Bean外,Spring还可以根据@Conditional决定是否创建某个Bean。

例如,我们对SmtpMailService添加如下注解:

@Component
@Conditional(OnSmtpEnvCondition.class)
public class SmtpMailService implements MailService {
    ...
}

它的意思是,如果满足OnSmtpEnvCondition的条件,才会创建SmtpMailService这个Bean。OnSmtpEnvCondition的条件是什么呢?我们看一下代码:

public class OnSmtpEnvCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "true".equalsIgnoreCase(System.getenv("smtp"));
    }
}

因此,OnSmtpEnvCondition的条件是存在环境变量smtp,值为true。这样,我们就可以通过环境变量来控制是否创建SmtpMailService

Spring只提供了@Conditional注解,具体判断逻辑还需要我们自己实现。Spring Boot提供了更多使用起来更简单的条件注解,例如,如果配置文件中存在app.smtp=true,则创建MailService

@Component
@ConditionalOnProperty(name="app.smtp", havingValue="true")
public class MailService {
    ...
}

如果当前classpath中存在类javax.mail.Transport,则创建MailService

@Component
@ConditionalOnClass(name = "javax.mail.Transport")
public class MailService {
    ...
}

后续我们会介绍Spring Boot的条件装配。我们以文件存储为例,假设我们需要保存用户上传的头像,并返回存储路径,在本地开发运行时,我们总是存储到文件:

@Component
@ConditionalOnProperty(name = "app.storage", havingValue = "file", matchIfMissing = true)
public class FileUploader implements Uploader {
    ...
}

在生产环境运行时,我们会把文件存储到类似AWS S3上:

@Component
@ConditionalOnProperty(name = "app.storage", havingValue = "s3")
public class S3Uploader implements Uploader {
    ...
}

其他需要存储的服务则注入Uploader

@Component
public class UserImageService {
    @Autowired
    Uploader uploader;
}

当应用程序检测到配置文件存在app.storage=s3时,自动使用S3Uploader,如果存在配置app.storage=file,或者配置app.storage不存在,则使用FileUploader

可见,使用条件注解,能更灵活地装配Bean。

小结

Spring允许通过@Profile配置不同的Bean;

Spring还提供了@Conditional来进行条件装配,Spring Boot在此基础上进一步提供了基于配置、Class、Bean等条件进行装配。