Spring IOC容器学习,Bean的学习;

Spring IOC容器学习,Bean的学习;

Bean是什么?

JavaBean是描述Java的软件组件模型,有点类似于Microsoft的COM组件概念。在Java模型中,通过JavaBean可以无限扩充Java程序的功能,通过JavaBean的组合可以快速的生成新的应用程序。对于程序员来说,最好的一点就是JavaBean可以实现代码的重复利用,另外对于程序的易维护性等等也有很重大的意义。

我的理解是对java类的一种包装,对其属性,数值,功能等进行修饰,然后交给IOC实例化,随时使用;

bean规范:

1.所有属性为private(不能是public)
2.提供默认构造方法(必须有一个不带参的构造器)
3.提供getter和sette

传统方式与IOC方式:

传统方式

​ 我们都是通过new的方式获取对象比如 User user1 = new User();

IOC方式(控制反转 Inversion Of Control ):

​ 负责管理bean,发布和获取bean;

​ 通过描述完成bean之间的依赖关系;

其实就是传统方式需要 我们自己买菜,然后根据各种属性啥的自定义这个菜怎么洗,怎么制作;

IOC方式的bean是已经描述好烹饪方式,然后IOC负责把菜烧出来(实例化)直接给我们;

注解方式使用IOC和bean:

方式1

首先定义一个类

package com.nhjia.pojo;

public class Food {
    private String name;
    private String cookingway;

       /* setter and getter 自行添加 */
       /* 无参构造器默认自动包括 */
}

其次定义配置文件:

package com.nhjia.pojo.test;

import com.nhjia.pojo.Food;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
/*表示这是一个配置文件*/
public class Appconfig {
    @Bean(name="food")
    /*该bean的名字,如果没有initFood会被作为名字存入IOC*/
    public Food initFood(){
        Food food = new Food();
        food.setName("猪肉");
        food.setCookingway("红烧肉");
        return food;
    }
}


"食物"买好之后,烹饪方式之后,就直接交给"后厨"IOC做出这道菜

package com.nhjia.pojo.test;

import com.nhjia.pojo.Food;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(Appconfig.class);
        /*通过AnnotationConfigApplicationContext读取Appconfig里的配置,将配置里的bean装配到IOC中 “获取菜和做菜要求”*/
        Food food = ctx.getBean(Food.class);
        /*获取实例化对象 “取菜”*/
        System.out.println(food.getName());
        System.out.println(food.getCookingway());
    }
}

输出结果:在这里插入图片描述

但是第一种方式,如果有很多种bean,都要写initclass,就会显得很繁琐,所以还有第二种方式,在bean上先进行装配,配置文件只要扫描哪些文件里有bean和bean的装配即可

方式2
package com.nhjia.pojo.FOOD;

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

@Component("food")
/*@Component表明这个类会被扫描*/
public class Food {
    @Value("猪肉")
    /*@Value表示给这个bean的装配,描述*/
    private String name;
    @Value("红烧肉")
    private String cookingway;

    /* setter and getter */
    }
}

配置文件:

package com.nhjia.pojo.test;

import com.nhjia.pojo.FOOD.Food;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
/*表示这是一个配置文件*/
@ComponentScan
/*@CompontScan表示进行扫描,但是第一种只扫描Appconfig类所在的包和子包package com.nhjia.pojo.test*/
@ComponentScan("com.nhjia.pojo.*")
/*表示在包com.nhjia.pojo和其子包中进行扫描也可以指明com.nhjia.pojo.FOOD*/
@ComponentScan(basePackages = {"com.nhjia.pojo.FOOD"})
/*指定包*/
@ComponentScan(basePackageClasses = {Food.class})
/*也可以指定类*/
public class Appconfig {
}

两种方式下的测试结果相同;

使用到的注解:
 @Configuration
/*表示这是一个配置文件*/
 @Bean(name="food")
 /*该bean的名字,如果没有initFood会被作为名字存入IOC*/


 @Component("food")
/*@Component表明这个类会被扫描*/
 @Value("猪肉")
/*@Value表示给这个bean的装配,描述*/
 @ComponentScan
/*@CompontScan表示进行扫描,但是第一种只扫描Appconfig类所在的包和子包package com.nhjia.pojo.test*/

依赖注入

上述只描述了一种bean类装配到IOC中,但是bean之间有依赖,比如某些厨师精通肉类制作,而某些厨师精于做蔬菜类;这时候猪肉bean就与肉类厨师bean有了依赖

因为厨师都会烹饪所以定义接口

package com.nhjia.pojo.cook;

public interface CookWay {
    public void cook ();
}

定义两种厨师:

package com.nhjia.pojo.cook;

import org.springframework.stereotype.Component;

@Component
public class cook1 implements CookWay{

    @Override
    public void cook() {
        System.out.println("cook1精通于肉类制作");
    }
}
---------------------------------------------------------
package com.nhjia.pojo.cook;

import org.springframework.stereotype.Component;
/*暂时不加 @Component*/
public class cook2 implements CookWay {
    @Override
    public void cook() {
        System.out.println("cook2精通于蔬菜类制作");
    }
}

Food类

package com.nhjia.pojo.FOOD;

import com.nhjia.pojo.cook.CookWay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("food1")
/*@Component表明这个类会被扫描*/
public class Food {
	  @Autowired
	/*用于注入,可以通过属性也可以通过名称,这里我们要注入厨师一,因为这里的cookway是属性,cook1具有这个属性,所以ioc把cook1的实例注入到Food中*/
    private CookWay cook = null;
    @Value("猪肉")
    /*@Value表示给这个bean的装配,描述*/
    private String name;
    @Value("红烧肉")
    private String cookingway;
    /* setter and getter */
    public void Cook(){
        System.out.println(this.name+"用于"+this.cookingway+"制作,而");
        cook.cook();
        System.out.println("所以邀请他来做");
    }
}

配置Appconfig.class

package com.nhjia.pojo.test;

import com.nhjia.pojo.FOOD.Food;
import com.nhjia.pojo.cook.cook1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
/*表示这是一个配置文件*/
@ComponentScan(basePackageClasses = {Food.class, cook1.class})
/*指定包*/
public class Appconfig {
}

最后测试中再加个food1.Cook();

测试结果:在这里插入图片描述

依赖注入成功!

多个依赖注入的bean选择

@Autowired

​ private CookWay cook = null;

CookWay为属性,根据属性寻找bean类;

但是当第二个厨师也加入@Component就会报错;因为具有同种属性的bean有两个,不知道使用哪个;

所以修改方式1:

 	@Autowired
    private CookWay cook1 = null;
/*直接根据Cookway这个属性和cook1这个bean的名称进行匹配*/

方法二:

@Component
@Primary
/*同属性下,有多个类时,Primary具有优先选择权*/
public class cook1 implements CookWay{

}

方法三:也是在有primary存在下,选择cook2的方法

 @Autowired
 @Qualifier("cook1")
 private CookWay cook = null;

带参构造器的装配:

 private CookWay cook = null;
    @Autowired
    public Food(@Qualifier("cook1") CookWay cook){
        this.cook=cook;
    }
使用到的注解:
	@Autowired
	/*用于注入,可以通过属性也可以通过名称,这里我们要注入厨师一,因为这里的cookway是属性,cook1具有这个属性,所以ioc把cook1的实例注入到Food中*/

	@Primary
	/*同属性下,有多个类时,Primary具有优先选择权*/
 	
	@Qualifier("cook1")

后续…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值