1. 程式人生 > >spring獲取bean的幾種方式

spring獲取bean的幾種方式

使用jdk:1.8、maven:3.3.3

spring獲取Bean的方式

pom.xml檔案內容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.ac.iie</groupId>
    <artifactId>spring-course</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.0.RELEASE</version>
        </dependency>
    </dependencies>
</project>

配置類MyConfig.java:

package com.edu.spring;

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

/**
 * 配置類
 */

@Configuration
public class MyConfig {

    // 配置一個bean
    @Bean
    public MyBean createMyBean(){
        return new MyBean();
    }

}

MyBean.java

package com.edu.spring;

public class MyBean {
}

主函式:App.java

package com.edu.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        // 從容器中獲取bean---從型別獲取
        System.out.println(context.getBean(MyBean.class));
        // 從容器中獲取bean---從名字獲取,預設名字是方法名
        System.out.println(context.getBean("createMyBean"));
        context.close();
    }
}

輸出結果如下:

com.edu.spring.MyBean@1445d7f
com.edu.spring.MyBean@1445d7f

如果需要指定bean名字,需要修改MyConfig.java:

@Configuration
public class MyConfig {

    // 配置一個bean
    @Bean(name = "myBean")
    public MyBean createMyBean(){
        return new MyBean();
    }

}

然後在App.java指定Bean的名字:這樣就無法根據方法名獲取Bean了

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        // 從容器中獲取bean---從型別獲取
        System.out.println(context.getBean(MyBean.class));
        // 從容器中獲取bean---從名字獲取,預設名字是方法名
        // System.out.println(context.getBean("createMyBean"));
        // 從容器中獲取bean---從指定名字獲取
        System.out.println(context.getBean("myBean"));
        context.close();
    }
}

Bean預設是單例

我們可以看到,Bean是單例的,兩次打印出的物件是一樣的。

如果我們想修改Bean的單例為多例,修改MyConfig.java如下(新增scope(prototype)):

@Configuration
public class MyConfig {

    // 配置一個bean
    @Bean(name = "myBean")
    @Scope("prototype")
    public MyBean createMyBean(){
        return new MyBean();
    }

}

列印如下:

com.edu.spring.MyBean@10b48321
com.edu.spring.MyBean@6b67034

FactoryBean

新建方法JeepFactoryBean.java

package com.edu.spring;

import org.springframework.beans.factory.FactoryBean;

public class JeepFactoryBean implements FactoryBean<Jeep> {

    /**
     * 建立的例項物件
     * @return
     * @throws Exception
     */
    @Override
    public Jeep getObject() throws Exception {
        return new Jeep();
    }

    /**
     *
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return Jeep.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

在MyConfig.java中新增配置:

    @Bean
    public JeepFactoryBean createJeepFactoryBean(){
        return new JeepFactoryBean();
    }

可以在App.java中得到Jeep.class。

System.out.println(context.getBean(Jeep.class));
System.out.println(context.getBean("createJeepFactoryBean"));

如果要獲取JeepFactoryBean本身,而不是工廠生產出的類,可以通過下面的兩種方式獲取:

System.out.println(context.getBean(JeepFactoryBean.class));
System.out.println(context.getBean("&createJeepFactoryBean"));

目前有兩種方式進行Bean的裝配,一種是使用FactoryBean,一種是原始方式

使用第三種裝配

新建CarFactory.java

public class CarFactory {
    public Car create(){
        return new Car();
    }
}

新建Car.java

配置MyConfig.java

    @Bean
    public Car createJeep(CarFactory carFactory){
        return carFactory.create();
    }

    @Bean
    public CarFactory createCarFactory(){
        return new CarFactory();
    }

獲取物件:

System.out.println(context.getBean(Car.class));

因為,在Bean的裝配過程中,需要引數的時候,spring會預設從當前容器中獲取到對應的引數,然後注入。

Bean初始化,在Bean初始化時,進行一些操作。

方式一:

建立Cat.java

package com.edu.spring;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Cat implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("====afterPropertiesSet====");
    }

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

配置MyConfig.java


    @Bean
    public Cat createCat(){
        return new Cat();
    }

獲得cat

System.out.println(context.getBean(Cat.class));

控制檯列印:

====afterPropertiesSet====
com.edu.spring.MyBean@7fe8ea47
com.edu.spring.MyBean@226a82c4
com.edu.spring.JeepFactoryBean@731f8236
com.edu.spring.JeepFactoryBean@731f8236
com.edu.spring.Jeep@255b53dc
com.edu.spring.Jeep@255b53dc
com.edu.spring.Car@1dd92fe2
com.edu.spring.Cat@6b53e23f
====destroy====

方法二:

建立Dog.java

package com.edu.spring;

public class Dog {
    public void myInit(){
        System.out.println("init=====");
    }
    public void myDestory(){
        System.out.println("destory===");
    }

}

在配置MyConfig.java時指定初始化時執行和銷燬時執行的方法

    @Bean(initMethod = "myInit", destroyMethod = "myDestory")
    public Dog createDog(){
        return new Dog();
    }

方式三:

新建Fish.java

package com.edu.spring;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class Fish {

    @PostConstruct
    public void initial(){
        System.out.println("fish init");
    }

    @PreDestroy
    public void close(){
        System.out.println("fish close");
    }

}

配置MyConfig.java

    @Bean
    public Fish createFish(){
        return new Fish();
    }

Bean裝配

新建User.java

package com.edu.spring;

import org.springframework.stereotype.Component;

@Component
public class User {
}

修改App.java,將User.class

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, User.class);
System.out.println(context.getBean(User.class));

但是使用@Component,無法使用@Bean(initMethod = "myInit", destroyMethod = "myDestory")設定初始化和銷燬的方法

此外,預設的名字是類名。可以指定名字:

@Component("myUs