Spring1.2 工厂/注解配置Bean

本文详细介绍了Spring中如何通过工厂配置(静态工厂、实例工厂、FactoryBean)来创建Bean,并探讨了注解配置Bean的方式,包括@Component及其衍生注解,以及实例间依赖的自动装配。此外,还提及了Spring 4.x中的泛型注入新特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PART ONE 工厂配置

通过工厂方法,FactoryBean 的方法配置Bean

一:静态工厂方法

静态工厂方法完成Bean 配置:通过直接调用某个类的静态方法就可以放回Bean实例
测试代码:

1. Bean 对应类:
public class Car {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    方便测试:创建有参构造函数
    public Car(String name){
        this.name = name;
    }
2. 静态工厂方法的定义
public class StaticBeansFactory {
    private static Map<String,Car> cars= new HashMap<>();

    static {
        cars.put("baoma",new Car("baoma"));
        cars.put("aodi",new Car("aodi"));
    }
    
    静态方法
    public static Car getCar(String name){
        return cars.get(name);
    }
}    
测试:
 	测试静态工厂方法配置bean
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-factory.xml");
    Car car = (Car)ctx.getBean("car1");
    System.out.println(car);  ||获取到aodi 这个Car 

通过静态工厂方法:首先要写好相应的静态方法

二:实例工厂方法

即首先要创建工厂的实例,再通过工厂实例获取目标Bean实例

测试代码:

1. 实例工厂
public class InstanceCarFactory {
    private Map<String,Car> cars = null;
    public InstanceCarFactory(){
        cars= new HashMap<>();
        cars.put("aodi",new Car("aodi"));
        cars.put("dazhong",new Car("dazhong"));
    }

    public Car getCar(String name){
        return cars.get(name);
    }
}
2. XML配置文件
    1. 配置工厂实例
   	 <bean id="carFactory" class="spring.beans_factory.InstanceCarFactory"></bean>
    2. 配置目标Bean实例
  		  <!--使用工厂实例的方法获取目标Bean 实例-->
  	  <bean id="car2" factory-bean="carFactory" factory-method="getCar">
       	 <constructor-arg value="dazhong"></constructor-arg>
 	  </bean>

总结:
工厂方法就是在工厂中完成实例的配置,定义一个获取的方法,在配置文件中通过相应的获获取方法配置目标Bean(在配置文件中将目标对象交给IOC容器(Bean))

三:FactoryBean

FactoryBean 是Spring提供给我们的一个组件(interface)

测试代码:

1. factoryBean implement FactoryBean
public class CarFactoryBean implements FactoryBean<Car> {
    //定义一个属性
    private String type ;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    // 返回Bean
    @Override
    public Car getObject() throws Exception {
        return new Car(type);
    }
    //返回bean 的类型
    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }
    //是否为单例
    @Override
    public boolean isSingleton() {
        return true;
    }
}
2. xml 配置文件
 <!--测试FactoryBean 配置Bean-->
    <bean id="car" class="spring.factorybean.CarFactoryBean">
        <!--如果factoryBean 中定义了属性也可以配置属性,<>property-->
        <property name="type" value="BMW"></property>
    </bean>
3. 测试
 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-factoryBean.xml");
        Car car = (Car)ctx.getBean("car");
        System.out.println(car);
4. 测试结果
Car{name='BMW'}

FactoryBean 配置适用于目标Bean中依赖了其他Bean的情况

以上配置方式都是基于XML配置文件的方式


PART TWO 通过注解配置Bean

通过注解配置Bean是更加常用的方式

一:将Bean添加到IOC容器中

  1. 组建扫描
    Spring从ClassPath 自动扫描,侦测,实例化具有特定注解的类将其添加到IOC容器中进行管理-----变为组件
    特定的注解:
    1. @Component : 基本注解,标识了一个受Spring管理的组件
    2. @Repository:标识了持久层组件
    3. @Service : 标识了业务层组件
    4. @Controller :标识了表现层组件

其实对于Spring来说这几个注解都是一样的,都标识了一个受Spring管理的组件,只是对于开发人员,为了项目的结构清晰,用单词将他们区分

对于扫描到的组件,Spring 的默认起名:类名的第一个字母小写,也可以通过注解的value 属性由开发人员自定义组件的名字
在配置文件中要配置扫描:< context:component-sacn >
2. < context:component-sacn > 配置

< context:component-sacn > 中的属性和子节点对扫描加以限制

1.属性: base-package=“包的全限定名” : Spring会扫描包下所有的包和子包。

1. 两个属性
2.两个子节点 
通过这四个的设置,对扫描的包进行限制

二:实例之间相互存在依赖的Bean配置

通过注解实现Bean与Bean之间的依赖关系
< context:component-sacn > 配置元素会自动注册AutowireAnnotationBeanPostProcessor 实例(后置处理器),该实例可以自动装配具有@Autowired , @resource @Inject 注解属性

也就是说,通过< context:component-sacn > 配置的Bean ,可以在bean 中直接使用@Autowired @Resource @ Inject 注入它所依赖的Bean实例

使用@Autowired 自动装配Bean:根据类的类型匹配

  1. 普通字段,一切有参数的方法上都可以应用@Autowired 都可以使用该注解;但是如果注入的Bean 在IOC容器中没有就会 抛出异常。

  2. 如果某一属性允许不被被设置(允许IOC 容器中没有该Bean)可以 将@Autowired 的required 属性设置为false,这样就不会报

  3. 如果IOC容器中有多个符合的Bean(类型符合),会根据Bean的名字和匹配的属性名去匹配;如果出现一个注入IOC容器中存在多个 Bean,就会抛出异常

  4. 出现上述问题的解决办法(有多个类型符合的Bean,但是没有与配置的属性名义一致的Bean):在配置Bean的时候就给默认命名一样的Bean起不一样的名字/和属性名或者字段名一致;或者在注入的时候指定注入哪一个Bean 注解 @Qualifier("Bean 的名字") 配置指定的Bean

  5. (了解) @Autowired 在数组上面,会将所有符合的Bean全部装配;在集合上面会见所有兼容的Bean全部装配,在Map上面Bean的名称为键,Bean实例为值

@Resource 和@Inject 和@Autowired 的用法类似,一般都使用@Autowired

三:spring 4.x 中的新特性 泛型注入

两个具有泛型类之间 互相存在引用关系,这样的依赖将会被子类继承
代码实例:

泛型类1.
class BaseRepository<T>{}
泛型类2.
class BaseService<T>{
@Autowire
private BaseRepository<T> repository;

public void test(){
 System.out.printf(repository);
 }
 }
 子类1.
 @Repository
 class UserRepository extends Baserepository<User>{}
 子类2.
 @Service
 class UserService extends BaseService<User>{}
测试:
UserService  userService = new UserService();
userService.test();

结果打印的是UserRepository
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值