SpringBoot 之 IOC

1、IoC的作用

IoC(控制反转),主要的作用就是降低代码之间的耦合程度。

2、Bean的装配

使用Spring boot生成对象需要几个步骤:
1、为需要生成对象的类打上@Component的注解标记,这些类会被放到IoC容器中。Component注解有一个Value属性,指定这个类用于被检索的名字,如果不指定,默认是把类名的首字母小写其余不变作为检索名。在这些类的属性上打上@Value注解可以为属性赋值。
2、定义一个配置文件类,加上@Configuration注解,这个类用于扫描IoC容器,找到需要装配的Bean。如果希望自动装配,不需要再配置文件中用@Bean手动配置,则在配置文件类中打上@ComponentScan注解标记。
3、测试装配,实例化一个ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class),传入配置文件,利用ctx中的getBean方法得到装配好的对象。

代码样例:

1、放入IoC容器的类:

package com.xiayto.springbootlearn.chapter3.aclazz;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component(value = "player")
public class Player {

    @Value("xiayto")
    private String name;

    @Value("100")
    private Double hp;

    public String getName() {
        return name;
    }

    public Double getHp() {
        return hp;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setHp(Double hp) {
        this.hp = hp;
    }
}

这里要注意,属性要加上getter和setter的方法,才能装配成功。

2、配置文件类:

package com.xiayto.springbootlearn.chapter3.aconfig;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.xiayto.springbootlearn.chapter3.aclazz")
public class Config {
}

这里的basePackages,可以指定扫描的路径,只会扫描路径下标记了@Component的类

3、测试:

package com.xiayto.springbootlearn.chapter3.atest;

import com.xiayto.springbootlearn.chapter3.aclazz.Player;
import com.xiayto.springbootlearn.chapter3.aconfig.Config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IoCTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
        Player player = ctx.getBean(Player.class);
        System.out.println(player.getName());
        System.out.println(player.getHp());
    }
}

3、自定义第三方Bean

想把第三方的包里面的类放到IoC容器里面,这时可以在配置类中,写生成类对象的方法,然后用@Bean注解标注。

代码例子:
首先引入第三方的包:

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

然后在配置文件中写生成方法,并加上Bean的注解:

package com.xiayto.springbootlearn.chapter3.aconfig;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Properties;


@Configuration
@ComponentScan(basePackages = "com.xiayto.springbootlearn.chapter3.aclazz")
public class Config {

    @Bean(name = "dataSource")
    public DataSource getDataSource(){
        Properties pros = new Properties();
        pros.setProperty("driver", "com.mysql.jdbc.Driver");
        pros.setProperty("url", "jdbc:mysql://localhost:3306/chapter3");
        pros.setProperty("username", "root");
        pros.setProperty("password", "123456");
        DataSource dataSource = null;
        try {
            dataSource = BasicDataSourceFactory.createDataSource(pros);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }
}

4、依赖注入

IoC除了可以生成实例对象,还可以解决IoC容器中,Bean之间的依赖问题,具体的做法是:
1、打上@Autowrited注解,实现Bean中的属性的自动注入
2、同样的,所有用于注入的类(包括被注入的类)打上@Component放入IoC容器中,容器自动扫描寻找注入的Bean。
3、寻找注入的过程如果出现多个Bean满足注入条件,用@Primary@Qualifier,其中@Primary注解用于提升优先级,当多个Bean满足注入条件优先选择@Primary标注的Bean,而@Qualifier用于指定注入的Bean。

代码例子:
这是一个动物服务人的例子,让动物自动装配到人的对象中:

package com.xiayto.springbootlearn.chapter3.dependencyInjection.IoCContainerClass;

import com.xiayto.springbootlearn.chapter3.dependencyInjection.Animal;
import com.xiayto.springbootlearn.chapter3.dependencyInjection.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NormalMan implements Person {

    @Autowired
    private Animal animal = null;

    @Override
    public void service() {
        this.animal.use();
    }

    @Override
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

其中实现接口只是为了加快书写速度,需要自动注入对象的属性前加上@Autowrited的注解。

写动物类:

package com.xiayto.springbootlearn.chapter3.dependencyInjection.IoCContainerClass;

import com.xiayto.springbootlearn.chapter3.dependencyInjection.Animal;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class Dog implements Animal {
    @Override
    public void use() {
        System.out.println("狗用于看门口");
    }
}

狗这个动物就会装配到ManLikeCat的实例对象中,这里假设一般人都喜欢狗,狗打上了@Primary的注解,优先装配狗。如果存在多种动物,我想装备别的动物,就需要用到@Qualifier这个注解:

package com.xiayto.springbootlearn.chapter3.dependencyInjection.IoCContainerClass;

import com.xiayto.springbootlearn.chapter3.dependencyInjection.Animal;
import com.xiayto.springbootlearn.chapter3.dependencyInjection.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class ManLikeCat implements Person {

    private Animal animal = null;

    @Override
    public void service() {
        this.animal.use();
    }

    @Override
    @Autowired
    @Qualifier("cat")
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

在另一个人的属性上,使用@Qualifier指定需要装配的Bean,@Autowired注解不仅可以用在属性上,也可以用在设置属性的方法上。

5、属性文件注入

Pom文件中加入

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
 </dependency>

系统会自动从application.properties读取属性值,例如可以在application.properties设定server.port=8097。

如果要自己设定属性文件:
1、新建一个<属性文件名>.properties,写上属性值
2、在配置文件中加入属性文件地址@PropertySource("classpath:<属性文件名>.properties")
3、在Bean的属性上,利用 @Value("${database.username}")注入属性

代码例子:
1、新建属性文件,jdbc.properties:

database.username=root2
database.password=1234567

2、配置文件中加入属性文件地址

package com.xiayto.springbootlearn.chapter3.aconfig;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@ComponentScan(basePackages = "com.xiayto.springbootlearn.chapter3.*")
@PropertySource("classpath:jdbc.properties")
public class Config {
}

3、在Component上利用Value注解设置属性

package com.xiayto.springbootlearn.chapter3.propertiesTest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PropertiesTest {

    @Value("${database.username}")
    private String username = null;

    @Value("${database.password}")
    private String password = null;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    @Value("${database.username}")
    public void setUsername(String username) {
        this.username = username;
    }

    @Value("${database.password}")
    public void setPassword(String password) {
        this.password = password;
    }
}

4、测试:

package com.xiayto.springbootlearn.chapter3.propertiesTest;


import com.xiayto.springbootlearn.chapter3.aconfig.Config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class IoCPropertiesTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
        PropertiesTest pt = ctx.getBean(PropertiesTest.class);
        System.out.println(pt.getUsername());
        System.out.println(pt.getPassword());
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值