【问题标题】:Creating object using spring annotations使用弹簧注解创建对象
【发布时间】:2019-03-19 10:20:13
【问题描述】:

我是春天的初学者。我浏览了一些在线教程并编写了一个简单的程序,但我无法理解它的价值。当我们使用 spring.xml 文件并使用 getBean 方法创建对象时。但是,在注释的情况下,我使用 new 创建对象,我认为这是不对的。请看下面的代码,如果我遵循的程序有问题,请告诉我。

Hello.java:

package bean;

import org.springframework.stereotype.Component;

@Component
public class Hello {

    String gender;

    public void print(){
        System.out.println("Hello world "+gender);
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

}

AppConfig.java:

package config;

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

import bean.Hello;

@Configuration
public class AppConfig {

    @Bean(name="h")
    public Hello getHello(){
        Hello h= new Hello();
        h.setGender("male");
        return h;
    }

}

Driver.java:

package client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import bean.Hello;
import config.AppConfig;

public class Driver {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ApplicationContext ct=new AnnotationConfigApplicationContext(AppConfig.class);

        Hello h=ct.getBean("h",Hello.class);

        h.print();

    }

}

正如您在 AppConfig.java 中看到的,我正在使用

创建我的类的对象
Hello h= new Hello();

这看起来有问题。如果我必须自己创建对象,那我们为什么需要弹簧。请建议我在这里做错了什么。

【问题讨论】:

  • Spring 对象可以通过 xml 文件进行配置。如果您想更改值,例如非常有用用于数据库连接或其他一些配置对象
  • 我想使用注解而不是 spring.xml 文件。
  • Hello h=ct.getBean("h",Hello.class); - 这有什么问题?也搜索 bean injection
  • 查看 AppConfig 类中的代码。
  • 您不应该使用 new 创建类 - 请参阅 autowired 或使用与 main 相同的方法

标签: java spring annotations


【解决方案1】:

Thera 有两种方法可以在 Spring Context 中创建 bean

  1. 使用@Component注解(委托创建Spring Framework)

@Component:类上面的注解表明这个类是一个组件,应该被自动检测和实例化。因此 Spring 组件 bean 将如下所示:

@Component
public class User {
  private String name;

  private String address;

  public String getName() {
return name;
  }

  public void setName(String name) {
this.name = name;
  }

  public String getAddress() {
return address;
  }

  public void setAddress(String address) {
this.address = address;
  }
}

使用组件扫描扫描您的 bean:

xml老派Spring配置:

  <context:component-scan base-package=”com.yourpackage” />

组件扫描(如果您使用 Spring Boot,它将包含在 @SpringBootAppilcation 中)

@ComponentScan(basePackageClasses = Yourclass.class)
  1. 使用@Configuration 注解:(您的实际选择)

将@Configuration 类与带有@bean 注释的方法一起使用。您应该在这里提供如何创建新的对象设置值(您的 getHello 方法):

 @Bean(name="h")
public Hello getHello(){
    Hello h= new Hello();
    h.setGender("male");
    return h;
}

【讨论】:

    【解决方案2】:

    编辑 当您使用 @Component("h") 时,您正在创建一个名称为 h 的 bean,该 bean 具有在 Hello 类中定义的某些属性。所以你不需要 Appconfig 类。而且你不应该尝试在除 Hello 类之外的其他地方更改 bean 属性(如 setGender)。 那么我什么时候应该使用配置类?当您不将 Hello 类标记为 bean 时(即不使用组件注释)。您创建一个 Hello 类对象,设置某些属性并将其标记为 bean(使用 @bean)。

    不,您不必自己创建对象。 将 Hello 类标记为 @Component("h"),您可以直接使用 Hello h=ct.getBean("h",Hello.class); 获取 bean。

    您还可以使用Autowired 注释将您的 bean 放在任何地方并做任何您想做的事情。

    【讨论】:

    • 那么我应该在 AppConfig 类中写什么。当前内容为:@Configuration public class AppConfig { @Bean(name="h") public Hello getHello(){ Hello h= new Hello(); h.setGender("男");返回 h; } }
    • 在 AppConfig 类中,您可以获取名为 h 的 bean 并添加属性。您需要执行以下操作 @Autowired @Qualifier("h") private Hello hello; // 获取 bean hello.setGender("male"); // 设置属性
    • 现在我在 hello.setGender("male"); 上得到空指针异常;你能告诉我 AppConfig 类的内容应该是什么
    【解决方案3】:

    您不需要在 AppConfig.java 类中显式创建 bean,因为您已经在 Hello.java 类上具有 @Component 注释。 它会自动创建bean。

    您可以在 main 中使用您的代码直接访问 bean,但您需要在 @Component 中指定 bean 的名称为“h”。

     ApplicationContext ct=new AnnotationConfigApplicationContext(AppConfig.class);
    
            Hello h=ct.getBean("h",Hello.class);
    
            h.print();
    

    【讨论】:

    • 那么AppConfig类的内容应该是什么
    • AppConfig 类中不会有内容。您可以在那里指定@ComponentScan,以便它扫描并处理指定的包。如果您有任何其他配置,那么您可以在 AppConfig 类中指定它们。
    【解决方案4】:

    您只需要使用Autowired 并拥有getter

    @Autowired
    private Hello hello;
    
    public Hello getHello () {return hello;}
    

    【讨论】:

      【解决方案5】:

      回答这个问题,因为没有公认的答案。所以,你所做的是让 SpringContainer 创建 bean 的一种方式,并且可以在其他地方使用。

      基本上,我们可以要求spring使用三种类型为我们创建对象。

      1. 基于 XML 的配置,
      2. 基于注释的配置,
      3. 基于 Java 的配置。

      您使用了基于 Java 的配置。在使用spring框架时,我们不应该使用“new”关键字来创建对象。在创建 DataSource 对象(提供数据库详细信息)等某些场景下,它很有用。

      所以,如果你想让 spring 为你创建对象以及对象属性,我们可以使用 @component 和 @value 注释。参考下面的代码,

      package com.vj.spring.springanno;
      
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Component;
      
      @Component
      public class Hello {
      
          @Value("dummy value")
          String gender;
      
          
          public void print(){
              System.out.println("Hello world "+gender);
          }
      
          public String getGender() {
              return gender;
          }
      
          public void setGender(String gender) {
              this.gender = gender;
          }
      
      }
      

      您的 Appconfig 类应该如下所示(也可以读取 cmets),

      package com.vj.spring.springanno;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration // makes this class similar to spring.xml(old school way)
      @ComponentScan("com.vj.spring") // replacement of <context:component-scan base-package=”com.yourpackage” /> in spring.xml
      public class AppConfig {
      
      
          public static void main(String[] args) {
      
              ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
              Hello hello = context.getBean(Hello.class); // or context.getBean("hello",Hello.class);
              hello.print();
      
          }
      }
      

      默认情况下,如果使用@component注解,它会创建像“hello”这样的引用名(类名的驼峰式)。如果你想这样指定参考名称,你可以像 @component("h") 那样做。

      【讨论】:

        猜你喜欢
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-02
        相关资源
        最近更新 更多