SprintBoot系列(三):模式注解的@Configuration

上一节,我们讲到SpringBoot的IOC思想

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/sprintboot%E7%B3%BB%E5%88%97%EF%BC%88%E4%BA%8C%EF%BC%89%EF%BC%9Aspringboot%E7%9A%84ioc%E6%80%9D%E6%83%B3/

现在主要讲解模式注解中的@Configuration(配置类

上一节的例子中,如果执行代码需要切换类,依然需要修改主业务逻辑的代码(如从Diana类切换到Fox类)

如何应对面向对象中的变化呢?

  • 策略模式:制定一个interface,然后多个类实现一个interface
  • 防御模式:一个类实现interface,然后通过修改类的属性即可完成需求

demo1策略模式:引入@Configuration

1.1、 在sample/hero创建一个类,并命令为Xing

切记该类不能加入Component,不然会报错

package com.fcors.fcors.sample.hero;

import com.fcors.fcors.sample.ISkill;

public class Xing implements ISkill {
    public Xing(){
        System.out.println("xing 被实例化~");
    }
    public void q(){
        System.out.println("xing Q");
    }
    public void w(){
        System.out.println("xing W");
    }
}

1.2、在sample创建一个类,命名为HeroConfiguration

在类的方法中前加入@Configuration;在具体的实现中加入@Bean

package com.fcors.fcors.sample;

import com.fcors.fcors.sample.hero.Xing;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HeroConfiguration {
    @Bean
    public ISkill xing(){
        return new Xing();
    }
}

1.3、在具体的执行代码调用

package com.fcors.fcors.api.v1;

import com.fcors.fcors.sample.ISkill;
import com.fcors.fcors.sample.hero.Diana;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/api/")
public class TestController {
    @Autowired
    private ISkill xing;

    @GetMapping("/test3")
    public String test2(){
        xing.q();
        return "Hello Fox is testing3~";
    }
}
JAVA、基础技术、技术与框架SprintBoot系列(三):模式注解的@Configuration插图

demo2:通过构造函数或者Setter(),通过修改属性完成需求(防御模式)

demo2.1 构造函数方式的(防御模式)

2.1.1、修改demo1的Xing类
package com.fcors.fcors.sample.hero;

import com.fcors.fcors.sample.ISkill;
import org.springframework.stereotype.Component;


public class Xing implements ISkill {

    private String Name ="Xing";
    /* 属性注入 */
    public Xing(String Name){
        this.Name=Name;
        System.out.println(String.format("%s 被实例化~",this.Name));
    }

    public void q(){
        System.out.println(String.format("%s Q",this.Name));
    }
    public void w(){
        System.out.println(String.format("%s W",this.Name));
    }
}
2.1.2、修改demo1的HeroConfiguration类
package com.fcors.fcors.sample;

import com.fcors.fcors.sample.hero.Xing;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HeroConfiguration {
    @Bean
    public ISkill xing(){
        return new Xing("HEllo");
    }
}

构造型传参完成

下面进行Setter传参讲解

2.2.1、修改demo1的Xing类

选中定义的参数,右键”Generate”–>Setter

package com.fcors.fcors.sample.hero;

import com.fcors.fcors.sample.ISkill;
import org.springframework.stereotype.Component;


public class Xing implements ISkill {
    private String Name ="Xing";

    public void setName(String name) {
        Name = name;
    }

    public void q(){
        System.out.println(String.format("%s Q",this.Name));
    }
    public void w(){
        System.out.println(String.format("%s W",this.Name));
    }
}
2.2.2、修改demo1的HeroConfiguration类
package com.fcors.fcors.sample;

import com.fcors.fcors.sample.hero.Xing;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HeroConfiguration {
    @Bean
    public ISkill xing(){
        Xing aaa =  new Xing();
        aaa.setName("Fcors");
        return aaa;
    }
}
JAVA、基础技术、技术与框架SprintBoot系列(三):模式注解的@Configuration插图1

为什么要隔离到配置文件中

  • 配置文件集中性
  • 清晰(没有业务逻辑)

demo3:把参数放在文件中

3.1把参数添加到main/resources/application.properties中

server.port=8081
 mysql.port=3306
 mysql.url=192.168.8.8

3.2在sample创建一个package(database)

在package中创建一个MySQL类,在sample下面创建一个接口(IConnect),让MySql类实现

MySql类。因为该类是通过configuration注入容器,所以不需要加入@component,如果此处加了,在配置类Configuration的文件添加@ Configuration 会报错

package com.fcors.fcors.sample.database;

import com.fcors.fcors.sample.IConnect;

public class MySql implements IConnect {

    private String Ip;

    public void setIp(String ip) {
        Ip = ip;
    }

    public void setPort(String port) {
        Port = port;
    }

    private String Port;

    public void connent(){
        System.out.println(String.format("IP:%s,+Port:%s",this.Ip,this.Port));
    }
}

IConnect的源码

package com.fcors.fcors.sample;

public interface IConnect {
    void connent();
}

3.3在/sample中创建一个配置类Configuration

此处采用Setter的方式。如果需要引用文件配置的参数,则在参数上面声明@Value(“${mysql.port}”)

package com.fcors.fcors.sample;

import com.fcors.fcors.sample.database.MySql;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DatabaseConfiguration {

    @Value("${mysql.ip}")
    private String ip;

    @Value("${mysql.port}")
    private String port;

    @Bean
    public IConnect mysql(){
        MySql aaa = new MySql();
        aaa.setIp(this.ip);
        aaa.setPort(this.port);
        return aaa;
    }
}

3.4、调用具体的bean

package com.fcors.fcors.api.v1;

import com.fcors.fcors.sample.IConnect;
import com.fcors.fcors.sample.ISkill;
import com.fcors.fcors.sample.database.MySql;
import com.fcors.fcors.sample.hero.Diana;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/api/")
public class TestController {
    @Autowired
    private IConnect mysql;

    @GetMapping("/test3")
    public String test2(){
        mysql.connent();
        return "Hello Fox is testing~";
    }



}
JAVA、基础技术、技术与框架SprintBoot系列(三):模式注解的@Configuration插图2

实验结束。

为什么需要把@Configuration单独一节讲解。因为把配置独立在文件中,才更好符合ICO的思想,才更好实现OCP【开闭原则】

http://www.fcors.com/%e6%8a%80%e6%9c%af%e4%b8%8e%e6%a1%86%e6%9e%b6/sprintboot%E7%B3%BB%E5%88%97%EF%BC%88%E5%9B%9B%EF%BC%89%EF%BC%9A%E5%8C%85%E6%89%AB%E6%8F%8F%E4%B8%8E%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/