(001)spring容器创建bean的两种方式

简单记录一下spring容器创建、装配、管理bean

1、使用@Configuration、@Bean的注解组合创建bean

  可以用两种方法获取bean,根据类名或者创建bean的方法名,如果不指定bean的名字,默认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>com.edu.spring</groupId>
    <artifactId>spring</artifactId>
    <version>1.0.0</version>

    <name>spring</name>
    <!-- FIXME change it to the project‘s website -->
    <url>http://www.example.com</url>

    <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>4.3.2.RELEASE</version>
        </dependency>
    </dependencies>

</project>

  MyBean.java如下:

package com.edu.spring;

public class MyBean {

}

  MyConfig.java如下:

package com.edu.spring;

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

@Configuration
public class MyConfig {

    @Bean
    public MyBean createMyBean() {
        return new 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);
        System.out.println(context.getBean(MyBean.class));
        System.out.println(context.getBean("createMyBean"));
        context.close();
    }
}

  运行结果如下:

  指定bean的名字,可以在@bean添加name属性,如下:

package com.edu.spring;

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

@Configuration
public class MyConfig {

    @Bean(name="myBean")
    public MyBean createMyBean() {
        return new MyBean();
    }
}

  同样获取bean时,将App.java中修改为bean的name中指定的,如下:

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);
        System.out.println(context.getBean(MyBean.class));
        System.out.println(context.getBean("myBean"));
        context.close();
    }
}

  运行结果如下:

  上面两个运行结果可以发现,bean是单例的,使用@Scope("prototype")将单例修改为多例:

package com.edu.spring;

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

@Configuration
public class MyConfig {

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

  运行结果如下:

  使用@Configuration、@Bean的注解组合的变体创建bean

  Car.java

package com.edu.spring;

public class Car {

}

  CarFactory.java

package com.edu.spring;

public class CarFactory {

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

  MyConfig.java   spring容器装配CarFactory这个bean,创建Car这个bean的时候,形参接收的是spring容器已经创建的CarFactory这个bean

package com.edu.spring;

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

@Configuration
public class MyConfig {

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

    @Bean
    public Car createCar(CarFactory factory){
        return factory.create();
    }
}

  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);
        System.out.println(context.getBean(Car.class));
        context.close();
    }
}

  运行结果如下:

2、实现FactoryBean接口创建bean

  FactoryBean有3个方法,获取对象、获取对象类型、默认不是单例,如下:

  RunnableFactoryBean.java实现FactoryBean接口如下:

package com.edu.spring;

import org.springframework.beans.factory.FactoryBean;

public class RunnableFactoryBean implements FactoryBean<Runnable> {

    @Override
    public Runnable getObject() throws Exception {
        // TODO Auto-generated method stub
        return () -> {};
    }

    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return Runnable.class;
    }

    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return true;
    }

}

  配置类MyConfig.java中给RunnableFactoryBean添加Bean注解如下:

package com.edu.spring;

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

@Configuration
public class MyConfig {

    @Bean
    public RunnableFactoryBean createRunnableFactoryBean(){
        return new RunnableFactoryBean();
    }
}

  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);
        System.out.println(context.getBean(RunnableFactoryBean.class));
        System.out.println(context.getBean(Runnable.class));
        context.close();
    }
}

  运行结果如下:

  可以看到RunnableFactoryBean与Runnable的Bean都可以获取,Runnable是用Lambda实现的,所以看起来有点怪,下面不用Lambda表达式

  Jeep.java

package com.edu.spring;

public class Jeep {

}

  RunnableFactoryBean.java

package com.edu.spring;

import org.springframework.beans.factory.FactoryBean;

public class RunnableFactoryBean implements FactoryBean<Jeep> {

    @Override
    public Jeep getObject() throws Exception {
        // TODO Auto-generated method stub
        return new Jeep();
    }

    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return Jeep.class;
    }

    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return true;
    }

}

  MyConfig.java

package com.edu.spring;

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

@Configuration
public class MyConfig {

    @Bean
    public RunnableFactoryBean createRunnableFactoryBean(){
        return new RunnableFactoryBean();
    }
}

  App.java 根据类获取与根据bean的名字获取是一样的

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);
        System.out.println(context.getBean(RunnableFactoryBean.class));
        System.out.println(context.getBean(Jeep.class));
        System.out.println(context.getBean("createRunnableFactoryBean"));
        context.close();
    }
}

  运行结果如下:

  将RunnableFactoryBean.java中改为不是单例

package com.edu.spring;

import org.springframework.beans.factory.FactoryBean;

public class RunnableFactoryBean implements FactoryBean<Jeep> {

    @Override
    public Jeep getObject() throws Exception {
        // TODO Auto-generated method stub
        return new Jeep();
    }

    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return Jeep.class;
    }

    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return false;
    }

}

  App.java 两次获取的bean不一样

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);
        System.out.println(context.getBean(RunnableFactoryBean.class));
        System.out.println(context.getBean(Jeep.class));
        System.out.println(context.getBean("createRunnableFactoryBean"));
        context.close();
    }
}

  运行结果如下:

  从MyConfig.java中可以看到,创建的bean是RunnableFactoryBean,根据名字获取:context.getBean("createRunnableFactoryBean"))得到的却是泛型中的类的bean:[email protected],这是因为RunnableFactoryBean实现了FactoryBean接口,这个接口是特殊的,如果要根据RunnableFactoryBean的名字获取bean,可以用下面方式:

  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);
        System.out.println(context.getBean(Jeep.class));
        System.out.println(context.getBean("createRunnableFactoryBean"));
        System.out.println(context.getBean(RunnableFactoryBean.class));
        System.out.println(context.getBean("&createRunnableFactoryBean"));
        context.close();
    }
}

   运行结果如下:

  

原文地址:https://www.cnblogs.com/javasl/p/11755746.html

时间: 2024-12-09 08:50:25

(001)spring容器创建bean的两种方式的相关文章

Spring Boot 整合 Shiro ,两种方式全总结!

在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot 整合 Shiro 的话题! 一般来说,Spring Security 和 Shiro 的比较如下: Spring Security 是一个重量级的安全管理框架:Shiro 则是一个轻量级的安全管理框架 Spring Security 概念复杂,配置繁琐:Shiro 概念简单.配置简单 Spring

创建TabHost的两种方式的简单分析

最近做了一个TabHost的界面,在做的过程中发现了一些问题,故和大家分享一下. 首先我的界面如下: 目前就我所知,创建TabHost有两种方式,第一种是继承TabActivity类,然后用getTabHost方法来得到一个TabHost的实例,然后就可以给这个TabHost添加Tab了.示例代码如下: [java] view plaincopy public class PlotHost extends TabActivity  { @Override protected void onCre

创建线程的两种方式比较Thread VS Runnable

1.首先来说说创建线程的两种方式 一种方式是继承Thread类,并重写run()方法 1 public class MyThread extends Thread{ 2 @Override 3 public void run() { 4 // TODO Auto-generated method stub 5 6 } 7 } 8 //线程使用 9 MyThread mt = new MyThread(); //创建线程 10 mt.start(); //启动线程 另外一种方式是实现Runnabl

黑马程序员——创建线程的两种方式

java中创建线程有两种方式: 1.继承Thread类 步骤: (1)定义一个类继承Thread类 (2)复写Thread类中的run()方法 (3)调用start()方法:启动线程及调用run()方法 2.实现Runnable接口的方式 步骤:(1)定义一个类实现Runnable接口 (2)覆盖Runnable接口中的run()方法,将线程要运行的代码放到该run方法中 (3)通过Thread类建立线程对象 (4)将实现Runable接口的类对象作为实际参数传递给Thread的构造函数. (5

Java并发编程-创建线程的两种方式及区别

转载请注明:http://blog.csdn.net/UniKylin/article/details/45016117 1.线程和进程的区别 并行:是多个任务在同一时间同时执行,例如多核计算机同时计算的任务可以理解为并行 并发:从微观上看是多个任务抢占一个CPU从而执行自己的任务,轮流执行任务,但是如果遇到资源冲突的时候并没有从根本提高执行效率.但是提高了CPU的使用效率. 前段时间在GitHub上的一幅图可以很好的阐述上面的概念非常形象 2.Java中创建线程的两种方式 1.第一种方式:直接

【java并发】传统线程技术中创建线程的两种方式

传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式大部分人可能都知道,但是为什么这样玩就可以呢?下面我们来详细分析一下这两种方法的来龙去脉. 1. 揭秘Thread中run()方法 上面我们看到这两种方式都跟run()方法有关,所以我们来看一下Thread的源码中run()方法到底都干了什么: @Override public void run()

AIR打开创建进程的两种方式

写在这里,方便查阅 NativeApplication.nativeApplication.autoExit = true;// 主窗体关闭也跟着关闭 Debug.trace('ToursLocalConnection :: appExePath = ' + appExePath);currFile = new File(appExePath);//currFile = new File("C:/Users/lenovo/Desktop/LZPC_Test/LZPC/uninstall.exe&

Spring定义Bean的两种方式:和@Bean

前言:    Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用. 什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean. 今天通过Spring官方文档来了解下,如何生成bean,如何使用呢? 1.通过XML的方式来生成一个bean    最简单也是最原始的一种方式,通过XML来定义一个bean,我们来看下其过程 1)创建entity,命名为Student @Data@AllArgsConstructor@NoArgsCon

k8s 创建资源的两种方式 - 每天5分钟玩转 Docker 容器技术(124)

命令 vs 配置文件 Kubernetes 支持两种方式创建资源: 1. 用 kubectl 命令直接创建,比如: kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2 在命令行中通过参数指定资源的属性. 2. 通过配置文件和 kubectl apply 创建,要完成前面同样的工作,可执行命令: kubectl apply -f nginx.yml nginx.yml 的内容为: 资源的属性写在配置文件中,文件格式为 YAML