最全Spring初始化Bean的方法

前言

spring作为企业级web应用的常青树,已经陪伴我们技术人很多年的春秋,给我们企业带来了效率的提升,给我们的工作带来了更多的方便,作为我们技术人也是应该多了解她,就像对待老婆,女朋友,男朋友一样,多了解她才能少吵架,多一些幸福,那么今天我们就来看一下Spring、Bean的初始化。

一、引入spring-context依赖

	<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
    </dependency>

二、编写配置类Config和测试类

1、定义配置类Config

/**
 * @ClassName Config
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/13 23:28
 * @Version 1.0
 **/
@Configuration
public class Config {

    @Bean(name = "mybean")
    @Scope("prototype")
    public MyBean createBean(){
        return new MyBean();
    }


    @Bean(name = "factoryBean")
    public MyBeanFactoryBean createMyBeanFactoryBean(){
        return new MyBeanFactoryBean();
    }

    @Bean
    public RoseFactory createRoseFactory(){
        return new RoseFactory();
    }

    @Bean
    public Rose createRose(RoseFactory roseFactory){
        return roseFactory.createRose();
    }

    @Bean
    public Animal createAnimal(){
        return new Animal();
    }

}

2、定义测试类


/**
 * @ClassName App
 * @Description TODO
 * @Author M行则将至
 * @Date 2021/11/13 23:26
 * @Version 1.0
 **/
public class App {

    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class, People.class,
                UserDao.class, UserService.class, UserController.class);
//        通过Bean来定义
//        MyBean bean = context.getBean(MyBean.class);
//        MyBean beanProtoType = context.getBean(MyBean.class);
//        System.out.println(bean);
//        System.out.println(beanProtoType);
//
//        Object createBean = context.getBean("mybean");
//        System.out.println("name:" + createBean);

//        通过工厂类型来获取Bean
//        MyBeanFactoryBean bean1 = context.getBean(MyBeanFactoryBean.class);
//        System.out.println(bean1);
//        System.out.println(bean1.getObject());
//        System.out.println(bean1.getObjectType());
//
//        Object factoryBean = context.getBean("factoryBean");
//        System.out.println(factoryBean);
//
//        Object bean = context.getBean("&factoryBean");
//        System.out.println(bean);

//        通过其他bean进行创建,被需要的bean会被spring容器自己创建
//        Rose bean = context.getBean(Rose.class);
//        System.out.println(bean);
//        通过Component注解进行创建
//        People bean = context.getBean(People.class);
//        System.out.println(bean);
//        Object people = context.getBean("people");
//        System.out.println(people);
//        通过Repository注解进行创建
//        UserDao bean1 = context.getBean(UserDao.class);
//        System.out.println(bean1);
//        Object userDao = context.getBean("userDao");
//        System.out.println(userDao);
//        通过Service注解实现
//        UserService bean = context.getBean(UserService.class);
//        System.out.println(bean);
//        通过Controller注解实现
//        UserController bean = context.getBean(UserController.class);
//        System.out.println(bean);
//        通过Resource注解实现
//        UserService bean = context.getBean(UserService.class);
//        System.out.println(bean);
//        bean初始化后的前后动作,通过实现接口InitializingBean和DisposableBean实现
//        People bean = context.getBean(People.class);
//        System.out.println(bean);
//        通过注解实现
        Animal bean = context.getBean(Animal.class);
        System.out.println(bean);
        context.close();
    }
}
2.1 通过Bean来定义

1、定义一个简单Bean

/**
 * @ClassName MyBean
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/13 23:32
 * @Version 1.0
 **/
public class MyBean {
}

2、在配置类config中配置MyBean,其实和在xml中配置是一样的,代码如下:

/**
 * @ClassName Config
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/13 23:28
 * @Version 1.0
 **/
@Configuration
public class Config {

    @Bean(name = "mybean")
    @Scope("prototype")
    public MyBean createBean(){
        return new MyBean();
    }
}

3、测试(测试类通过上文中的运行即可)运行结果如下:

com.xzjz.simple.MyBean@6385cb26

4、spring中的Bean默认是单例的,但是可以通过Scope(“prototype”),来设置为原型模型,这样每次就可以获取一个新的对象,运行结果如下所示:

com.xzjz.simple.MyBean@19dc67c2
com.xzjz.simple.MyBean@221af3c0
name:com.xzjz.simple.MyBean@62bd765

兄弟姐们可以通过注释Config类中的注解来测试不同的情况,其中Bean如果不定义别名的话,context.getBean(“方法名”)获取对象,在这里就是context.getBean(“createBean”)

2.2 通过工厂类型来获取Bean

1、定义我们自己的对象


/**
 * @ClassName BeanFactory
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 12:09
 * @Version 1.0
 **/
public class BeanFactory {
}

2、定义MyBeanFactoryBean ,实现FactoryBean并实现其的方法,getObject返回对象,getObjectType返回对象的类型。


/**
 * @ClassName MyBeanFactoryBean
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 12:05
 * @Version 1.0
 **/
public class MyBeanFactoryBean implements FactoryBean<BeanFactory> {

    /**
     * 获取对象
     * @return
     * @throws Exception
     */
    @Override
    public BeanFactory getObject() throws Exception {
        return new BeanFactory();
    }

    /**
     * 获取对象的类型
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return BeanFactory.class;
    }
}

3、测试(测试类通过上文中的运行即可)运行结果如下,我们可以看到如果通过类型获取,那么得到的是MyBeanFactoryBean的类型,可以通过getObject和getObjectType获取对象及其类型,通过名字的话,获取到的是工厂对象生产出来的对象,我们一般在spring中是这种取法,但是我们还想获取其原型怎么办呢?即在名字前加&即可获得。

com.xzjz.factorybean.MyBeanFactoryBean@6b53e23f
com.xzjz.factorybean.BeanFactory@64d2d351
class com.xzjz.factorybean.BeanFactory
com.xzjz.factorybean.BeanFactory@1b68b9a4
com.xzjz.factorybean.MyBeanFactoryBean@6b53e23f

4、步骤4中的&符是怎么知道的呢?我们看源码BeanFactory,定义了一个工厂bean的前缀,就是从这里获取的,上边的注释也解释的非常清楚。

public interface BeanFactory {

	/**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
	 * will return the factory, not the instance returned by the factory.
	 */
	String FACTORY_BEAN_PREFIX = "&";
	//后边的其他代码省略,有兴趣的可以自行查看
}
2.3 通过其他bean进行创建,被需要的bean会被spring容器自己创建

1、定义我们自己的对象rose

/**
 * @ClassName Rose
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 12:31
 * @Version 1.0
 **/
public class Rose {
}

2、定义产生该对象的工厂类RoseFactory

/**
 * @ClassName RoseFactory
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 12:32
 * @Version 1.0
 **/
public class RoseFactory {

    public  Rose createRose(){
        return new Rose();
    }
}

3、测试(测试类通过上文中的运行即可)运行结果如下,缺少的roseFactory对象,spring容器会自动寻找上下文中的对象进行注入,如果没有的话会报错could not autowire,No Beans of ‘RoseFactory’ type found

com.xzjz.yilai.Rose@6328d34a
2.4 通过Component注解进行声明

1、定义bean


/**
 * @ClassName People
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:08
 * @Version 1.0
 **/
@Component("people")
public class People {
}

2、测试(查看上文中App的定义)运行结果如下:

com.xzjz.component.People@145eaa29
com.xzjz.component.People@145eaa29
2.5 通过Repository创建对象

1、定义UserDao对象


/**
 * @ClassName UserDao
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:23
 * @Version 1.0
 **/
@Repository //该注解一般用在dao层上
public class UserDao {
}

2、测试结果如下所示

com.xzjz.repository.UserDao@41ee392b
com.xzjz.repository.UserDao@41ee392b
2.6 通过Service注解实现

1、创建UserService

/**
 * @ClassName UserService
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:28
 * @Version 1.0
 **/
@Service //该注解一般用在业务层
public class UserService {
}

2、测试结果如下所示:

com.xzjz.service.UserService@157632c9
2.7 通过Controller注解实现

1、创建UserController

/**
 * @ClassName UserController
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:32
 * @Version 1.0
 **/
@Controller //该注解一般在视图层
public class UserController {
}

2、测试如下所示:

com.xzjz.controller.UserController@275710fc
2.8 通过Resource初始化

1、定义Resource修饰的Bean

/**
 * @ClassName UserService
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:28
 * @Version 1.0
 **/
@Service //该注解一般用在业务层
public class UserService {

    @Resource
    private People people;

    @Override
    public String toString() {
        return "UserService{" +
                "people=" + people +
                '}';
    }
}

2、测试运行如下,可以看到people已经被初始化

UserService{people=com.xzjz.component.People@568bf312}

3、其实还有一个JSR-330的注解Inject注解,需要导入javax.inject包,这个咱们自行研究

2.9 bean初始化后的前后动作,通过实现接口InitializingBean和DisposableBean实现

1、实现InitializingBean和DisposableBean

/**
 * @ClassName People
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 13:08
 * @Version 1.0
 **/
@Component("people")
public class People implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("=====afterPropertiesSet=======");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("========destroy===========");
    }
}

2、测试结果如下:

=====afterPropertiesSet=======
com.xzjz.component.People@589b3632
========destroy===========
2.10 通过注解实现bean初始化时的动作

1、定义bean

/**
 * @ClassName Animal
 * @Description TODO
 * @Author 行则将至
 * @Date 2021/11/14 15:23
 * @Version 1.0
 **/
public class Animal {

    @PostConstruct
    public void before(){
        System.out.println("======before======");
    }

    @PreDestroy
    public void after(){
        System.out.println("=======after======");
    }
}

2、测试结果如下:

======before======
com.xzjz.afterbefore.Animal@2145433b
=======after======

三、结语

道阻且长,行则将至,行而不辍,未来可期,加油。
如果你热爱编码,欢迎微信搜索程序猿每日分享,和我们大家一起打怪升级。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿每日分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值