spring ioc 1

spring ioc其實就是控制翻轉,幫你創建對象,不用在自己創建。在需要聚合引入時也會處理對象之間的關係。

ioc其實就是分兩步:

第一步:將自己的對象寫好後加上能被spring掃描的註解,通常的註解有:@Configuration,@Component,@Service,@Controller等等,看似好多被掃描標識的註解,其實具有被掃描功能的只有@Component,其他註解內部只是包含@Component所有才有了被掃描的功能,因爲不會有人喜歡寫重複冗餘的代碼,尤其是工具,所以spring也不會例外。

第二步:掃描的註解是:@ComponentScan,通過指定或默認掃描的範圍去掃描標識過的對象,然後創建並加載到ico容器中,可通過ico容器的getBean方法將指定的對象取出使用。

1.ioc容器:org.springframework.context.ApplicationContext,這只是個接口,下面有很多的實現類,也就是說有很多的ico實現容器。我們這裏使用的是其中一個叫import org.springframework.context.annotation.AnnotationConfigApplicationContext;的容器做demo演示。

2.掃描註解:@ComponentScan(basePackages = {"com.mr.li.*" }/* , excludeFilters = {@Filter(classes = {Person.class, Animal.class})} */)掃描註解見名知意就是用來掃描需要加載到ico容器中的java類的。可以指明掃描範圍,例如填寫包名,也可過濾哪些不被掃描 excludeFilters中的內容就是不被掃描的。掃描的註解也較多如:@ComponentScans,@EntityScan,@EnableAsync

上代碼:

1:先指定掃描哪些包,包括在裏面也創建一些被ioc加載的bean

package com.mr.li.config;


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

import com.mr.li.entity.User;

@Configuration
@ComponentScan(basePackages = {
        "com.mr.li.*" }/* , excludeFilters = {@Filter(classes = {Person.class, Animal.class})} */)
public class AppConfig {
    
    @Bean(value = "user1")
    public User getUser() {
        User user = new User();
        user.setId(1000);
        user.setName("旺達");
        return user;
    }
    
    @Bean(value = "user2")
    public User getUser2() {
        User user = new User();
        user.setId(1001);
        user.setName("天天");
        return user;
    }
}

2.創建一些服務接口

package com.mr.li.service;

public interface Person {

    void behavior();
    
}
package com.mr.li.service;

public interface Animal {

    void behavior();
}

3,給這些接口一些實現類

package com.mr.li.service.impl;

import org.springframework.stereotype.Component;

import com.mr.li.service.Animal;

@Component
public class Cat implements Animal {

    @Override
    public void behavior() {
        System.out.println("喵喵喵~~~~~~~~~");
    }

}
package com.mr.li.service.impl;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import com.mr.li.service.Animal;

@Primary
@Component
public class Dog implements Animal {

    @Override
    public void behavior() {
        System.out.println("汪汪汪~~~~~~~~~~");
    }

}
package com.mr.li.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.mr.li.service.Animal;
import com.mr.li.service.Person;

@Component
public class Man implements Person {

    @Qualifier("cat")
    @Autowired
    private Animal animal;
    
    @Override
    public void behavior() {
        animal.behavior();
    }
}

4.user演示類

package com.mr.li.entity;

import lombok.Data;

@Data
//@Component
public class User {
    
//    @Value(value = "100") //這種直接賦值的優先級最高
    private long id;
    
//    @Value(value = "章大狗")
    private String name;
    
    @Override
    public String toString() {
        return "id:"+ id + "name:" + name;
    }
}

5.測試

package com.mr.li.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.mr.li.config.AppConfig;
import com.mr.li.entity.User;
import com.mr.li.service.Person;
import com.mr.li.service.impl.Man;

import lombok.extern.slf4j.Slf4j;


@Slf4j
public class Test {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        Person person = ctx.getBean(Man.class);
        person.behavior();
//        User user = ctx.getBean(User.class);
        User user = ctx.getBean("user2", User.class);
        log.info("user:{}", user);
    }
}

以上代碼的行爲:

AppConfg:掃描了定義的包,然後在身演示創建一些bean,可以看到同樣類型的bean給了不同的名稱,這些類對象在掃描後會被加載到ico容器中去,其中在ico中存儲的名稱就是指定的名稱,如果沒指定則使用方法名首字母小寫作爲名稱。

Man:人物類,他實現了Person接口,然後自身加了@Component被掃描註解,我們會發現它裏面有引入Animal類的,加了@Autowired註解,此註解就是通過ioc引入Animal的實現類對象,但他有2個實現類對象,所以需要指定到底使用哪個實現類作爲對象引入。三種方式:

第一種:直接將變量名animal改爲他的子類的類名即可,這個類名是ioc中的變量名,默認會將類首字母小寫,也可指定。

第二種:在需要引入的實現類上加@Primary註解,此註解意思是如果沒有特殊情況就加載他,但在兩個實現類上都加也不行,他的優先級小於@Qualifier註解。

第三種:@Qualifier註解,加載引入的類上同@Autowired一起存在,同樣需要指定ioc中存儲對應的變量名。

Test:演示了,創建一個ioc容器,加載是他內部的事,注意傳入加載的第一類即可。然後演示從ioc中取出對象並使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章