热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

SpringBoot中的条件判断的介绍(附代码)

​本篇文章给大家带来的内容是关于SpringBoot中的条件判断的介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

本篇文章给大家带来的内容是关于Spring Boot中的条件判断的介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

Spring Boot中的那些Conditional

spring boot中为我们提供了丰富的Conditional来让我们得以非常方便的在项目中向容器中添加Bean。本文主要是对各个注解进行解释并辅以代码说明其用途。

所有ConditionalOnXXX的注解都可以放置在class或是method上,如果方式在class上,则会决定该class中所有的@Bean注解方法是否执行。

@Conditional

下面其他的Conditional注解均是语法糖,可以通过下面的方法自定义ConditionalOnXXX
Conditional注解定义如下,接收实现Condition接口的class数组。

public @interface Conditional {
    Class[] value();
}

而Condition接口只有一个matchs方法,返回是否匹配的结果。

public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

通过操作系统进行条件判断,从而进行Bean配置。当Window时,实例化Bill的Person对象,当Linux时,实例化Linus的Person对象。

//LinuxCondition,为方便起见,去掉判断代码,直接返回true了
public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return true;
    }
}
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了
public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
        return false;
    }
}
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private Integer age;
}
//配置类
@Configuration
public class BeanConfig {

    @Bean(name = "bill")
    @Conditional({WindowsCondition.class})
    public Person person1(){
        return new Person("Bill Gates",62);
    }

    @Bean("linus")
    @Conditional({LinuxCondition.class})
    public Person person2(){
        return new Person("Linus",48);
    }
}
public class AppTest {
    AnnotationConfigApplicationContext applicatiOnContext= new AnnotationConfigApplicationContext(BeanConfig.class);

    @Test
    public void test(){
        String osName = applicationContext.getEnvironment().getProperty("os.name");
        System.out.println("当前系统为:" + osName);
        Map map = applicationContext.getBeansOfType(Person.class);
        System.out.println(map);
    }
}

输出的结果:

当前系统为:Mac OS X
{linus=Person(name=Linus, age=48)}

@ConditionalOnBean & @ConditionalOnMissingBean

这两个注解会对Bean容器中的Bean对象进行判断,使用的例子是配置的时候,如果发现如果没有Computer实例,则实例化一个备用电脑。

@Data
@AllArgsConstructor
@ToString
public class Computer {
    private String name;
}
@Configuration
public class BeanConfig {
    @Bean(name = "notebookPC")
    public Computer computer1(){
        return new Computer("笔记本电脑");
    }

    @ConditionalOnMissingBean(Computer.class)
    @Bean("reservePC")
    public Computer computer2(){
        return new Computer("备用电脑");
    }
}
public class TestApp {
    AnnotationConfigApplicationContext applicatiOnContext= new AnnotationConfigApplicationContext(BeanConfig.class);
    @Test
    public void test1(){
        Map map = applicationContext.getBeansOfType(Computer.class);
        System.out.println(map);
    }
}

修改BeanConfig,如果注释掉第一个@Bean,会实例化备用电脑,否则就不会实例化备用电脑

@ConditionalOnClass & @ConditionalOnMissingClass

这个注解会判断类路径上是否有指定的类,一开始看到的时候比较困惑,类路径上如果没有指定的class,那编译也通过不了啊...这个主要用于集成相同功能的第三方组件时用,只要类路径上有该组件的类,就进行自动配置,比如spring boot web在自动配置视图组件时,是用Velocity,还是Thymeleaf,或是freemaker时,使用的就是这种方式。
例子是两套盔甲A(光明套装)和B(暗黑套装),如果A不在则配置B。

public interface Fighter {
    void fight();
}
public class FighterA implements Fighter {
    @Override
    public void fight() {
        System.out.println("使用光明套装");
    }
}
public class FighterB implements Fighter {
    @Override
    public void fight() {
        System.out.println("使用暗黑套装");
    }
}

Van是武士,使用套装进行战斗

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Van {
    private Fighter fighter;
    public void fight(){
        fighter.fight();
    }
}

VanConfigA/B实例化武士

@Configuration
@ConditionalOnClass({FighterA.class})
public class VanConfigA {
    @Primary
    @Bean
    public Van vanA(){
        return new Van(new FighterA());
    }
}
@Configuration
@ConditionalOnClass({FighterB.class})
public class VanConfigB {
    @Bean
    public Van vanB(){
        return new Van(new FighterB());
    }
}

测试类,默认情况,如果套装AB都在类路径上,两套都会加载,A会设置为PRIMARY,如果在target class中将FightA.class删除,则只会加载套装B。

@SpringBootApplication
public class TestApp implements CommandLineRunner {
    @Autowired
    private Van van;
    public static void main(String[] args) {
        SpringApplication.run(TestApp.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        //do something
       van.fight();
    }
}

另外,尝试将两个VanConfigA/B合并,将注解ConditionalOnClass放到方法上,如果删除一个套装就会运行出错。

@ConditionalOnExpress

依据表达式进行条件判断,这个作用和@ConditionalOnProperty大部分情况可以通用,表达式更灵活一点,因为可以使用SpEL。例子中会判断properties中test.enabled的值进行判断。BeanConfig分别对布尔,字符串和数字三种类型进行判断。数字尝试了很多其他的方式均不行,比如直接使用==,貌似配置的属性都会当成字符串来处理。

@Data
public class TestBean {
    private String name;
}
@Configuration
@ConditionalOnExpression("#{${test.enabled:true} }")
//@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')")
//@ConditionalOnExpression("new Integer('${test.account}')==1")
public class BeanConfig {
    @Bean
    public TestBean testBean(){
        return new TestBean("我是美猴王");
    }
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
    @Autowired
    private TestBean testBean;

    public static void main(String[] args) {
        SpringApplication.run(TestAppCommand.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(testBean.getName());
    }
}

@ConditionalOnProperty

适合对单个Property进行条件判断,而上面的@ConditionalOnExpress适合面对较为复杂的情况,比如多个property的关联比较。这个例子也给了三种基本类型的条件判断,不过貌似均当成字符串就可以...

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestBean {
    private String name;
}
@Configuration
@ConditionalOnProperty(prefix = "test", name="enabled", havingValue = "true",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="account", havingValue = "1",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="name1", havingValue = "zz",matchIfMissing = false)
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean("我是美猴王");
    }
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
    @Autowired
    private TestBean testBean;
    public static void main(String[] args) {
        SpringApplication.run(TestAppCommand.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(testBean.getName());

    }
}

@ConditionalOnJava

可以通过java的版本进行判断。

@Data
public class TestBean {
}
@Configuration
@ConditionalOnJava(JavaVersion.EIGHT)
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanConfig.class);
    @Test
    public void test(){
        Map map = context.getBeansOfType(TestBean.class);
        System.out.println(map);
    }
}

@ConditionalOnResource

通过指定的资源文件是否存在进行条件判断,比如判断ehcache.properties来决定是否自动装配ehcache组件。

@Data
public class TestBean {
}
@Configuration
@ConditionalOnResource(resources = "classpath:application.yml")
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanConfig.class);

    @Test
    public void test(){
        Map map = context.getBeansOfType(TestBean.class);
        System.out.println(map);
    }
}

@ConditionalOnSingleCandidate

这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了PRIMARY。例子中,BeanB装配的时候需要看BeanA的装配情况,所以BeanBConfig要排在BeanAConfig之后.可以修改BeanAConfig,将@Primary注解去掉,或者把三个@Bean注解去掉,BeanB就不会实例化了。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BeanA {
    private String name;
}
@Configuration
public class BeanAConfig {

    @Bean
    @Primary
    public BeanA bean1(){
        return new BeanA("bean1");
    }
    @Bean(autowireCandidate = false)
    public BeanA bean2(){
        return new BeanA("bean2");
    }
    //@Bean(autowireCandidate = false)
    public BeanA bean3(){
        return new BeanA("bean3");
    }
}
@Data
public class BeanB {
}
@Configuration
@AutoConfigureAfter(BeanAConfig.class)
@ConditionalOnSingleCandidate(BeanA.class)
public class BeanBConfig {

    @Bean
    public BeanB targetBean(){
        return new BeanB();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class);

    @Test
    public void test(){
        Map map = context.getBeansOfType(BeanA.class);
        System.out.println(map);
        Map map2 = context.getBeansOfType(BeanB.class);
        System.out.println(map2);
    }
}

@ConditionalOnNotWebApplication & @ConditionalOnWebApplication

判断当前环境是否是Web应用。







1 小时前发布

Spring Boot中的那些条件判断
  • java

19 次阅读 · 读完需要 31 分钟



0

Spring Boot中的那些Conditional

spring boot中为我们提供了丰富的Conditional来让我们得以非常方便的在项目中向容器中添加Bean。本文主要是对各个注解进行解释并辅以代码说明其用途。

所有ConditionalOnXXX的注解都可以放置在class或是method上,如果方式在class上,则会决定该class中所有的@Bean注解方法是否执行。

@Conditional

下面其他的Conditional注解均是语法糖,可以通过下面的方法自定义ConditionalOnXXX
Conditional注解定义如下,接收实现Condition接口的class数组。

public @interface Conditional {
    Class[] value();
}

而Condition接口只有一个matchs方法,返回是否匹配的结果。

public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

通过操作系统进行条件判断,从而进行Bean配置。当Window时,实例化Bill的Person对象,当Linux时,实例化Linus的Person对象。

//LinuxCondition,为方便起见,去掉判断代码,直接返回true了
public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return true;
    }
}
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了
public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
        return false;
    }
}
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private Integer age;
}
//配置类
@Configuration
public class BeanConfig {

    @Bean(name = "bill")
    @Conditional({WindowsCondition.class})
    public Person person1(){
        return new Person("Bill Gates",62);
    }

    @Bean("linus")
    @Conditional({LinuxCondition.class})
    public Person person2(){
        return new Person("Linus",48);
    }
}
public class AppTest {
    AnnotationConfigApplicationContext applicatiOnContext= new AnnotationConfigApplicationContext(BeanConfig.class);

    @Test
    public void test(){
        String osName = applicationContext.getEnvironment().getProperty("os.name");
        System.out.println("当前系统为:" + osName);
        Map map = applicationContext.getBeansOfType(Person.class);
        System.out.println(map);
    }
}

输出的结果:

当前系统为:Mac OS X
{linus=Person(name=Linus, age=48)}

@ConditionalOnBean & @ConditionalOnMissingBean

这两个注解会对Bean容器中的Bean对象进行判断,使用的例子是配置的时候,如果发现如果没有Computer实例,则实例化一个备用电脑。

@Data
@AllArgsConstructor
@ToString
public class Computer {
    private String name;
}
@Configuration
public class BeanConfig {
    @Bean(name = "notebookPC")
    public Computer computer1(){
        return new Computer("笔记本电脑");
    }

    @ConditionalOnMissingBean(Computer.class)
    @Bean("reservePC")
    public Computer computer2(){
        return new Computer("备用电脑");
    }
}
public class TestApp {
    AnnotationConfigApplicationContext applicatiOnContext= new AnnotationConfigApplicationContext(BeanConfig.class);
    @Test
    public void test1(){
        Map map = applicationContext.getBeansOfType(Computer.class);
        System.out.println(map);
    }
}

修改BeanConfig,如果注释掉第一个@Bean,会实例化备用电脑,否则就不会实例化备用电脑

@ConditionalOnClass & @ConditionalOnMissingClass

这个注解会判断类路径上是否有指定的类,一开始看到的时候比较困惑,类路径上如果没有指定的class,那编译也通过不了啊...这个主要用于集成相同功能的第三方组件时用,只要类路径上有该组件的类,就进行自动配置,比如spring boot web在自动配置视图组件时,是用Velocity,还是Thymeleaf,或是freemaker时,使用的就是这种方式。
例子是两套盔甲A(光明套装)和B(暗黑套装),如果A不在则配置B。

public interface Fighter {
    void fight();
}
public class FighterA implements Fighter {
    @Override
    public void fight() {
        System.out.println("使用光明套装");
    }
}
public class FighterB implements Fighter {
    @Override
    public void fight() {
        System.out.println("使用暗黑套装");
    }
}

Van是武士,使用套装进行战斗

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Van {
    private Fighter fighter;
    public void fight(){
        fighter.fight();
    }
}

VanConfigA/B实例化武士

@Configuration
@ConditionalOnClass({FighterA.class})
public class VanConfigA {
    @Primary
    @Bean
    public Van vanA(){
        return new Van(new FighterA());
    }
}
@Configuration
@ConditionalOnClass({FighterB.class})
public class VanConfigB {
    @Bean
    public Van vanB(){
        return new Van(new FighterB());
    }
}

测试类,默认情况,如果套装AB都在类路径上,两套都会加载,A会设置为PRIMARY,如果在target class中将FightA.class删除,则只会加载套装B。

@SpringBootApplication
public class TestApp implements CommandLineRunner {
    @Autowired
    private Van van;
    public static void main(String[] args) {
        SpringApplication.run(TestApp.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        //do something
       van.fight();
    }
}

另外,尝试将两个VanConfigA/B合并,将注解ConditionalOnClass放到方法上,如果删除一个套装就会运行出错。

@ConditionalOnExpress

依据表达式进行条件判断,这个作用和@ConditionalOnProperty大部分情况可以通用,表达式更灵活一点,因为可以使用SpEL。例子中会判断properties中test.enabled的值进行判断。BeanConfig分别对布尔,字符串和数字三种类型进行判断。数字尝试了很多其他的方式均不行,比如直接使用==,貌似配置的属性都会当成字符串来处理。

@Data
public class TestBean {
    private String name;
}
@Configuration
@ConditionalOnExpression("#{${test.enabled:true} }")
//@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')")
//@ConditionalOnExpression("new Integer('${test.account}')==1")
public class BeanConfig {
    @Bean
    public TestBean testBean(){
        return new TestBean("我是美猴王");
    }
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
    @Autowired
    private TestBean testBean;

    public static void main(String[] args) {
        SpringApplication.run(TestAppCommand.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(testBean.getName());
    }
}

@ConditionalOnProperty

适合对单个Property进行条件判断,而上面的@ConditionalOnExpress适合面对较为复杂的情况,比如多个property的关联比较。这个例子也给了三种基本类型的条件判断,不过貌似均当成字符串就可以...

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestBean {
    private String name;
}
@Configuration
@ConditionalOnProperty(prefix = "test", name="enabled", havingValue = "true",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="account", havingValue = "1",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="name1", havingValue = "zz",matchIfMissing = false)
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean("我是美猴王");
    }
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
    @Autowired
    private TestBean testBean;
    public static void main(String[] args) {
        SpringApplication.run(TestAppCommand.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(testBean.getName());

    }
}

@ConditionalOnJava

可以通过java的版本进行判断。

@Data
public class TestBean {
}
@Configuration
@ConditionalOnJava(JavaVersion.EIGHT)
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanConfig.class);
    @Test
    public void test(){
        Map map = context.getBeansOfType(TestBean.class);
        System.out.println(map);
    }
}

@ConditionalOnResource

通过指定的资源文件是否存在进行条件判断,比如判断ehcache.properties来决定是否自动装配ehcache组件。

@Data
public class TestBean {
}
@Configuration
@ConditionalOnResource(resources = "classpath:application.yml")
public class BeanConfig {

    @Bean
    public TestBean testBean(){
        return new TestBean();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanConfig.class);

    @Test
    public void test(){
        Map map = context.getBeansOfType(TestBean.class);
        System.out.println(map);
    }
}

@ConditionalOnSingleCandidate

这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了PRIMARY。例子中,BeanB装配的时候需要看BeanA的装配情况,所以BeanBConfig要排在BeanAConfig之后.可以修改BeanAConfig,将@Primary注解去掉,或者把三个@Bean注解去掉,BeanB就不会实例化了。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BeanA {
    private String name;
}
@Configuration
public class BeanAConfig {

    @Bean
    @Primary
    public BeanA bean1(){
        return new BeanA("bean1");
    }
    @Bean(autowireCandidate = false)
    public BeanA bean2(){
        return new BeanA("bean2");
    }
    //@Bean(autowireCandidate = false)
    public BeanA bean3(){
        return new BeanA("bean3");
    }
}
@Data
public class BeanB {
}
@Configuration
@AutoConfigureAfter(BeanAConfig.class)
@ConditionalOnSingleCandidate(BeanA.class)
public class BeanBConfig {

    @Bean
    public BeanB targetBean(){
        return new BeanB();
    }
}
public class TestApp {
    AnnotationConfigApplicationContext cOntext= new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class);

    @Test
    public void test(){
        Map map = context.getBeansOfType(BeanA.class);
        System.out.println(map);
        Map map2 = context.getBeansOfType(BeanB.class);
        System.out.println(map2);
    }
}

@ConditionalOnNotWebApplication & @ConditionalOnWebApplication

判断当前环境是否是Web应用。


  • 评论



    载入中...

    显示更多评论


    以上就是Spring Boot中的条件判断的介绍(附代码)的详细内容,更多请关注其它相关文章!


推荐阅读
  • 本文详细介绍了如何在预装Ubuntu系统的笔记本电脑上安装Windows 7。针对没有光驱的情况,提供了通过USB安装的具体方法,并解决了分区、驱动器无法识别等问题。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • Linux中的yum安装软件
    yum俗称大黄狗作用:解决安装软件包的依赖关系当安装依赖关系的软件包时,会将依赖的软件包一起安装。本地yum:需要yum源,光驱挂载。yum源:(刚开始查看yum源中的内容就是上图 ... [详细]
  • 通常情况下,修改my.cnf配置文件后需要重启MySQL服务才能使新参数生效。然而,通过特定命令可以在不重启服务的情况下实现配置的即时更新。本文将详细介绍如何在线调整MySQL配置,并验证其有效性。 ... [详细]
  • Symfony是一个功能强大的PHP框架,以其依赖注入(DI)特性著称。许多流行的PHP框架如Drupal和Laravel的核心组件都基于Symfony构建。本文将详细介绍Symfony的安装方法及其基本使用。 ... [详细]
  • 本文详细介绍了 Python 中的条件语句和循环结构。主要内容包括:1. 分支语句(if...elif...else);2. 循环语句(for, while 及嵌套循环);3. 控制循环的语句(break, continue, else)。通过具体示例,帮助读者更好地理解和应用这些语句。 ... [详细]
  • 2012年7月30日,语言岛团队宣布其智能记单词软件V0.3.4.554版本正式开源。该版本不仅支持跨平台使用,还引入了多项创新功能,旨在帮助用户更高效地记忆单词。 ... [详细]
  • 本文详细介绍了如何在 Android 中使用值动画(ValueAnimator)来动态调整 ImageView 的高度,并探讨了相关的关键属性和方法,包括图片填充后的高度、原始图片高度、动画变化因子以及布局重置等。 ... [详细]
  • 本文详细介绍了如何在不同操作系统和设备上设置和配置网络连接的IP地址,涵盖静态和动态IP地址的设置方法。同时,提供了关于路由器和机顶盒等设备的IP配置指南。 ... [详细]
  • Appium + Java 自动化测试中处理页面空白区域点击问题
    在进行移动应用自动化测试时,有时会遇到某些页面没有返回按钮,只能通过点击空白区域返回的情况。本文将探讨如何在Appium + Java环境中有效解决此类问题,并提供详细的解决方案。 ... [详细]
  • 如何清除Chrome浏览器地址栏的特定历史记录
    在使用Chrome浏览器时,你可能会发现地址栏保存了大量浏览记录。有时你可能希望删除某些特定的历史记录而不影响其他数据。本文将详细介绍如何单独删除地址栏中的特定记录以及批量清除所有历史记录的方法。 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • 本文详细介绍了如何解压并安装MySQL集群压缩包,创建用户和组,初始化数据库,配置环境变量,并启动相关服务。此外,还提供了详细的命令行操作步骤和常见问题的解决方案。 ... [详细]
  • CentOS 6.8 上安装 Oracle 10.2.0.1 的常见问题及解决方案
    本文记录了在 CentOS 6.8 系统上安装 Oracle 10.2.0.1 数据库时遇到的问题及解决方法,包括依赖库缺失、操作系统版本不兼容、用户权限不足等问题。 ... [详细]
author-avatar
黄宗翰琼琦莉雯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有