2013-06-08 37 views
11

Tôi mới đến Spring.Làm cách nào để truyền các tham số động tới các bean Spring

Đây là mã đăng ký đậu:

<bean id="user" class="User_Imple"> </bean> 
<bean id="userdeff" class="User"> </bean> 

và đây là lớp bean tôi:

public class User_Imple implements Master_interface { 

    private int id; 
    private User user; // here user is another class 

    public User_Imple() { 
     super(); 
    } 

    public User_Imple(int id, User user) { 
     super(); 
     this.id = id; 
     this.user = user; 
    } 

    // some extra functions here.... 
} 

và đây là phương pháp chính của tôi để thực hiện thao tác:

public static void main(String arg[]) { 

    ApplicationContext context = new ClassPathXmlApplicationContext("/bean.xml"); 
    Master_interface master = (Master_interface)context.getBean("user"); 

    // here is my some operations.. 
    int id = ... 
    User user = ... 

    // here is where i want to get a Spring bean 
    User_Imple userImpl; //want Spring-managed bean created with above params 
} 

Bây giờ tôi muốn gọi hàm tạo này với các tham số và các tham số này được tạo động trong metho chính của tôi ds. Đây là những gì tôi có ý nghĩa bởi tôi muốn truyền động - không tĩnh, như được khai báo trong tệp bean.config của tôi.

Trả lời

2

Vui lòng xem Constructor injection.

Ngoài ra, hãy xem IntializingBeanBeanPostProcessor để chặn vòng đời khác của mùa xuân.

+2

bạn có thể vui lòng trích dẫn tài liệu tham khảo cho lý do tại sao 'tiêm setter' được ưa thích hơn constructor –

+0

"Nhóm nghiên cứu mùa xuân nói chung ủng hộ xây dựng tiêm vì nó cho phép người ta triển khai các thành phần ứng dụng như các đối tượng bất biến và để đảm bảo rằng các phụ thuộc bắt buộc không phải là null ... Setter injection chỉ nên được sử dụng cho các phụ thuộc tùy chọn có thể được gán giá trị mặc định hợp lý trong lớp "- http: // docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html –

+1

Tôi nghĩ bằng "động" người dùng có nghĩa là anh ta muốn chuyển các đối số trong chính tôi thod, hoặc nói chung tại thời điểm nhận đậu. gọi getBean (...) và các đối số truyền trực tiếp hoạt động, nhưng việc chuyển cuộc gọi này đến một trình định vị (mẫu Service Locator) có thể được thực hiện để tránh sự phụ thuộc vào Spring Framework trong mã của bạn. Locator có thể được chuyển vào như bean thay vào đó, và định vị ApplicationContextAware có thể gọi getBean (bean, arg1, arg2 ...). Bean phạm vi nên được "nguyên mẫu". cũng xem: http://stackoverflow.com/questions/812415/why-is-springs-applicationcontext-getbean-considered-bad –

0

Có lẽ để cho các User_Imple là một Pojo bình thường (thay vì một bean mùa xuân) sẽ giải quyết vấn đề của bạn?

<!-- Only use User as a Spring Bean --> 
<bean id="userdeff" class="User"></bean> 

Java:

public static void main(String arg[]) 
{ 
    ApplicationContext context =new ClassPathXmlApplicationContext("/bean.xml"); 
    User user = context.getBean(User.class); 

    int id = // dynamic id 
    Master_interface master = new User_Imple(id, user); 
} 
+0

ya @matsev tốt của nó, nếu tôi có ít không. của lớp chúng tôi trực tiếp sử dụng POJO nhưng trong MVC chúng tôi hoàn toàn ẩn các tập tin kinh doanh .. sau đó chúng tôi đi qua đậu .. –

+0

Sau đó, bạn cần một lớp nhà máy mà bạn có thể tham khảo từ mùa xuân. Mùa xuân sử dụng (nhiều hơn hoặc ít hơn) chỉ Singletons – cljk

1

tiêm Constructor có thể giúp bạn. Trong trường hợp này, bạn có thể cần tạo POJO với ID và người dùng làm thuộc tính của nó và chuyển POJO tới hàm tạo. Trong constructor injection trong file config bạn có thể tham khảo constructor này với pojo làm tham chiếu. Vì vậy, bạn sẽ xử lý giá trị động của dữ liệu trong ID và Người dùng.

Hy vọng điều này sẽ giúp ích !!

18

Nếu tôi nhận bạn đúng, thì câu trả lời đúng là sử dụng #getBean (String beanName, Object ... args) mà sẽ vượt qua đối số cho đậu. Tôi có thể chỉ cho bạn, làm thế nào nó được thực hiện cho cấu hình dựa trên java, nhưng bạn sẽ phải tìm cách nó được thực hiện cho cấu hình dựa trên xml.

@Configuration 
public class ApplicationConfiguration { 

    @Bean 
    @Scope("prototype") //As we want to create several beans with different args, right? 
    String hello(String name) { 
    return "Hello, " + name; 
    } 
} 

//and later in your application 

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); 
String helloCat = (String) context.getBean("hello", "Cat"); 
String helloDog = (String) context.getBean("hello", "Dog"); 

Đây có phải là những gì bạn đang tìm kiếm không?

Cập nhật. Câu trả lời này nhận được quá nhiều upvotes và không ai nhìn vào bình luận của tôi. Mặc dù đó là một giải pháp cho vấn đề, nó được coi là kiểu chống mùa xuân và bạn không nên sử dụng nó! Có nhiều cách khác nhau để làm những điều đúng sử dụng nhà máy, tra cứu-phương pháp, vv ..

Vui lòng sử dụng sau SO gửi như là một điểm tham chiếu: create beans at runtime

+3

Xin lưu ý rằng nó không phải là giải pháp tốt nhất khi sử dụng "DI", bởi vì thực sự ở đây chúng tôi có kinda "dịch vụ định vị" (mà là đối diện với DI). Thông thường, khi bạn gặp quá nhiều context.getBean nó có nghĩa là một cái gì đó được thực hiện một cách sai lầm. –

1

Tôi nghĩ rằng câu trả lời đề xuất ở trên để sử dụng constructor injection/setter injection không hoạt động hoàn hảo cho trường hợp sử dụng mà bạn đang tìm kiếm. Mùa xuân nhiều hơn hoặc ít hơn có giá trị đối số tĩnh cho các nhà xây dựng/setters. Tôi không nhìn thấy một cách để tự động vượt qua các giá trị để có được một Bean từ Spring Container. Tuy nhiên, nếu bạn muốn nhận được các trường hợp User_Imple động, tôi sẽ khuyên bạn sử dụng một lớp nhà máy User_Imple_Factory


    public class User_Imple_factory { 
     private static ApplicationContext context =new ClassPathXmlApplicationContext("/bean.xml"); 

     public User_Imple createUserImple(int id) { 
      User user = context.getBean("User"); 
      return new User_Imple(id, user); 
     } 
    } 
 
+0

triển khai ApplicationContextAware để tránh tạo một ApplicationContext mới có thể được tạo ở một nơi khác. –

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