2010-09-07 27 views
56

Đây là mã của tôi:Sử dụng mùa xuân 3 autowire trong một độc lập Java ứng dụng

public class Main { 

    public static void main(String[] args) { 
     Main p = new Main(); 
     p.start(args); 
    } 

    @Autowired 
    private MyBean myBean; 
    private void start(String[] args) { 
     ApplicationContext context = 
      new ClassPathXmlApplicationContext("META-INF/config.xml"); 
     System.out.println("my beans method: " + myBean.getStr()); 
    } 
} 

@Service 
public class MyBean { 
    public String getStr() { 
     return "string"; 
    } 
} 

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
    <context:annotation-config /> 
    <context:component-scan base-package="mypackage"/> 
</beans> 

Tại sao không làm việc này? Tôi nhận được NullPointerException. Có thể sử dụng autowiring trong một ứng dụng độc lập không?

+0

Cố gắng làm cho câu hỏi của bạn có thể đọc được. Và cho chúng tôi thấy dấu vết ngăn xếp ngoại lệ. – skaffman

+0

Tôi duy trì một ví dụ hoạt động tại đây: http://tshikatshikaaa.blogspot.com/2012/08/spring-ioc-container-with-annotations.html – JVerstry

Trả lời

118

Spring hoạt động trong ứng dụng độc lập. Bạn đang sử dụng sai cách để tạo ra một bean mùa xuân. Cách chính xác để thực hiện điều này như sau:

@Component 
public class Main { 

    public static void main(String[] args) { 
     ApplicationContext context = 
      new ClassPathXmlApplicationContext("META-INF/config.xml"); 

     Main p = context.getBean(Main.class); 
     p.start(args); 
    } 

    @Autowired 
    private MyBean myBean; 
    private void start(String[] args) { 
     System.out.println("my beans method: " + myBean.getStr()); 
    } 
} 

@Service 
public class MyBean { 
    public String getStr() { 
     return "string"; 
    } 
} 

Trong trường hợp đầu tiên (câu hỏi), bạn tự tạo đối tượng thay vì lấy nó từ ngữ cảnh mùa xuân. Vì vậy, Spring không có cơ hội để Autowire các phụ thuộc (gây ra các NullPointerException).

Trong trường hợp thứ hai (câu trả lời này), bạn lấy hạt từ ngữ cảnh mùa xuân và do đó nó là Spring được quản lý và Spring sẽ xử lý autowiring.

+0

Không phải @Autowired là một chiến lược tất cả trong? Hoặc là mùa xuân quản lý _all_ việc tạo đối tượng không có, nhưng bạn không thể thêm @Autowired vào một số trường trong callstack của bạn và khởi tạo chúng với ..(). – Cojones

+0

Nếu chỉ có một đối tượng duy nhất trong callstack của bạn được khởi tạo với new ..() nó sẽ không hoạt động đúng không? – Cojones

+2

@Cojones, bạn có thể autowire một số đậu và tạo ra những người khác với mới, nếu không làm thế nào bạn sẽ có thể gọi là 'new ArrayList() ', ví dụ? Nếu bạn có một lớp với các tham số autowired và bạn khởi tạo nó với 'new' thì autowiring sẽ không diễn ra. – Paul

12

Mùa xuân đang chuyển khỏi các tệp XML và sử dụng chú thích nhiều. Ví dụ sau đây là một ứng dụng Spring độc lập đơn giản sử dụng chú thích thay vì các tệp XML.

package com.zetcode.bean; 

import org.springframework.stereotype.Component; 

@Component 
public class Message { 

    private String message = "Hello there!"; 

    public void setMessage(String message){ 

     this.message = message; 
    } 

    public String getMessage(){ 

     return message; 
    } 
} 

Đây là một loại đậu đơn giản. Nó được trang trí với chú thích @Component để tự động phát hiện bởi vùng chứa Spring.

package com.zetcode.main; 

import com.zetcode.bean.Message; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.ComponentScan; 

@ComponentScan(basePackages = "com.zetcode") 
public class Application { 

    public static void main(String[] args) { 

     ApplicationContext context 
       = new AnnotationConfigApplicationContext(Application.class); 

     Application p = context.getBean(Application.class); 
     p.start(); 
    } 

    @Autowired 
    private Message message; 
    private void start() { 
     System.out.println("Message: " + message.getMessage()); 
    } 
} 

Đây là lớp chính Application. Các tìm kiếm chú thích @ComponentScan cho các thành phần. Chú thích @Autowired đưa đậu vào biến số message. AnnotationConfigApplicationContext được sử dụng để tạo bối cảnh ứng dụng Spring.

My Standalone Spring tutorial cho biết cách tạo ứng dụng Spring độc lập với cả XML và chú thích.

0

Đối với mùa xuân 4, sử dụng Spring Boot chúng ta có thể có ví dụ sau đây mà không sử dụng chống mô hình nhận được Bean từ ApplicationContext trực tiếp:

package com.yourproject; 

@SpringBootApplication 
public class TestBed implements CommandLineRunner { 

    private MyService myService; 

    @Autowired 
    public TestBed(MyService myService){ 
     this.myService = myService; 
    } 

    public static void main(String... args) { 
     SpringApplication.run(TestBed.class, args); 
    } 

    @Override 
    public void run(String... strings) throws Exception { 
     System.out.println("myService: " + MyService); 
    } 

} 

@Service 
public class MyService{ 
    public String getSomething() { 
     return "something"; 
    } 
} 

Hãy chắc chắn rằng tất cả các dịch vụ tiêm của bạn đang được com.yourproject hoặc các gói con của nó.

Các vấn đề liên quan