কীভাবে বসন্তে অটোয়ারিং কাজ করে?


510

নিয়ন্ত্রণের বিপরীতমুখীতাটি সম্পর্কে আমি কিছুটা বিভ্রান্ত ( IoC)Spring

বলুন আমার কাছে একটি পরিষেবা শ্রেণি আছে UserServiceImplUserService ইন্টারফেস প্রয়োগ করে ।

এটা কিভাবে হবে @Autowired ?

এবং আমার মধ্যে Controllers, আমি কিভাবে হবেinstantiateinstance এই পরিষেবাটির একজন ?

আমি কি কেবল নিম্নলিখিতগুলি করতে পারি?

UserService userService = new UserServiceImpl();

উত্তর:


703

প্রথম এবং সবচেয়ে গুরুত্বপূর্ণ - সমস্ত বসন্ত মটরশুটি পরিচালনা করা হয় - তারা একটি পাত্রে "লাইভ" থাকে, "অ্যাপ্লিকেশন প্রসঙ্গে" বলে।

দ্বিতীয়ত, প্রতিটি প্রয়োগের সেই প্রসঙ্গে একটি এন্ট্রি পয়েন্ট রয়েছে। ওয়েব অ্যাপ্লিকেশনগুলির একটি সার্লেট রয়েছে, জেএসএফ একটি এল-রিসলভার ইত্যাদি ব্যবহার করে Also এছাড়াও, এমন একটি জায়গা রয়েছে যেখানে অ্যাপ্লিকেশন প্রসঙ্গটি বুটস্ট্র্যাপযুক্ত এবং সমস্ত মটরশুটি - স্বীকৃত। ওয়েব অ্যাপ্লিকেশনগুলিতে এটি একটি সূচনা শ্রোতা হতে পারে।

একটি শিমের উদাহরণটি অন্য শিমের উদাহরণে পছন্দসই ক্ষেত্রের মধ্যে রাখার মাধ্যমে অটোয়রিং ঘটে। উভয় শ্রেণীর মটরশুটি হওয়া উচিত, অর্থাত্ অ্যাপ্লিকেশন প্রসঙ্গে বাঁচতে তাদের সংজ্ঞা দেওয়া উচিত।

আবেদনের প্রসঙ্গে "জীবিত" কী? এর অর্থ হল যে প্রসঙ্গটি আপনি নয়, বস্তুগুলিকে তাত্ক্ষণিক করে তোলে। অর্থাৎ - আপনি কখনই বানাবেন নাnew UserServiceImpl() - ধারকটি প্রতিটি ইনজেকশন পয়েন্ট খুঁজে পায় এবং সেখানে একটি উদাহরণ সেট করে।

আপনার নিয়ন্ত্রকগুলিতে আপনার কেবলমাত্র নিম্নলিখিতগুলি রয়েছেন:

@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {

    // Tells the application context to inject an instance of UserService here
    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    public void login(@RequestParam("username") String username,
           @RequestParam("password") String password) {

        // The UserServiceImpl is already injected and you can use it
        userService.login(username, password);

    }
}

কয়েকটি নোট:

  • আপনার applicationContext.xmlসক্ষম করা উচিত <context:component-scan>যাতে শ্রেণীর জন্য স্ক্যান করা হয় @Controller, @Serviceইত্যাদি টীকা।
  • একটি স্প্রিং-এমভিসি অ্যাপ্লিকেশনের প্রবেশের স্থানটি ডিসপ্যাচারসারভাইলেট, তবে এটি আপনার কাছ থেকে লুকানো থাকে এবং তাই অ্যাপ্লিকেশন প্রসঙ্গে সরাসরি ইন্টারঅ্যাকশন এবং বুটস্ট্র্যাপিং ঘটনার পিছনে ঘটে।
  • UserServiceImplশিম হিসাবেও সংজ্ঞায়িত করা উচিত - হয় টীকাটি <bean id=".." class="..">ব্যবহার করে বা ব্যবহার করে @Service। যেহেতু এটি একমাত্র বাস্তবায়নকারী UserServiceহবে, তাই এটি ইনজেকশন দেওয়া হবে।
  • @Autowiredটিকাটি ছাড়াও , বসন্তটি এক্সএমএল-কনফিগারযোগ্য অটোয়্যারিং ব্যবহার করতে পারে। সেক্ষেত্রে বিদ্যমান শিমের সাথে মেলে এমন একটি নাম বা টাইপ রয়েছে এমন সমস্ত ক্ষেত্র স্বয়ংক্রিয়ভাবে শিমের ইনজেকশনের ব্যবস্থা করে। প্রকৃতপক্ষে, এটি স্বয়ংক্রিয়করণের প্রাথমিক ধারণা ছিল - কোনও কনফিগারেশন ছাড়াই নির্ভরতাগুলির সাথে ক্ষেত্রগুলি ইনজেকশন করা। অন্যান্য টীকা পছন্দ @Inject, @Resourceএছাড়াও ব্যবহার করা যাবে।

7
হ্যাঁ, ব্যবহারকারীর পরিষেবা আইপিএল পরিষেবা দিয়ে টীকায়িত হয় এবং ইউজার সার্ভিস ইন্টারফেস
বোঝো

16
ডিফল্ট স্কোপটি সিঙ্গলটন, সুতরাং আপনার কাছে শিমের কেবলমাত্র একটি উদাহরণ থাকবে, যা একাধিক জায়গায় ইনজেকশন করা হয়। যদি আপনি স্পষ্টভাবে "প্রোটোটাইপ" হিসাবে স্কোপটি সংজ্ঞায়িত করেন তবে একাধিক উদাহরণ উপস্থিত থাকবে, সম্ভবত অলস (কনফিগারেশনের উপর নির্ভর করে)
বোঝো

2
আপনার পোস্টের জন্য অনেক ধন্যবাদ, এটি আমার জন্য সত্যিই জিনিসগুলি সাফ করেছে। সম্পর্কিত 'যেহেতু এটি একমাত্র প্রয়োগকারী বা ব্যবহারকারীর পরিষেবা হবে, তাই এটি ইনজেকশন দেওয়া হবে।' - যদি একাধিক ক্লাস থাকে যা ব্যবহারকারীদের পরিষেবা প্রয়োগ করে? বসন্ত কীভাবে জানতে পারে যে এটি ব্যবহার করা উচিত?
Shishigami

7
যদি কোনও "প্রাথমিক" হিসাবে মনোনীত হয় তবে এটি এটি ব্যবহার করে। অন্যথায় এটি একটি ব্যতিক্রম নিক্ষেপ করে
বোঝো

3
না, ইউজার সার্ভিস শুধুমাত্র একবার তৈরি করা হয়েছে, এটি
সিঙ্গলটন

64

আপনি টীকাগুলির রুট বা শিমের এক্সএমএল সংজ্ঞা রুট চান কিনা তা নির্ভর করে।

বলুন আপনার শিমের সংজ্ঞা দেওয়া আছে আপনার applicationContext.xml:

<beans ...>

    <bean id="userService" class="com.foo.UserServiceImpl"/>

    <bean id="fooController" class="com.foo.FooController"/>

</beans>

অ্যাপ্লিকেশন শুরু হওয়ার পরে স্বতঃশক্তি হয় happens সুতরাং, ইনfooController , যা যুক্তি স্বার্থে UserServiceImplক্লাসটি ব্যবহার করতে চায় আপনি নীচে এটির জন্য মন্তব্য করতে চান:

public class FooController {

    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

এটি যখন দেখবে @Autowired, স্প্রিং একটি শ্রেণীর সন্ধান করবে যা সম্পত্তিটির সাথে মেলে applicationContextএবং এটি স্বয়ংক্রিয়ভাবে ইনজেক্ট করবে। আপনার যদি একাধিক UserServiceশিম থাকে, তবে এটি কোনটি ব্যবহার করা উচিত তা আপনাকে যোগ্যতা অর্জন করতে হবে।

আপনি যদি নিম্নলিখিতটি করেন:

UserService service = new UserServiceImpl();

@Autowiredআপনি নিজেরাই সেট না করা এটি পছন্দ করবে না ।


2
তাই সংজ্ঞায়িত ব্যবহার কি bean idমধ্যে applicationContext.xml। আমাদেরকে টাইপের userServiceসাথে ভেরিয়েবল নির্ধারণ করতে হবে UserService। সুতরাং কেন xmlফাইল প্রবেশ করুন।
ভাইপার

20

@Autowired এটি স্প্রিং 2.5 এ চালু হয় এবং এটি কেবল ইনজেকশনের জন্য ব্যবহৃত হয়।

উদাহরণ স্বরূপ:

class A {

    private int id;

    // With setter and getter method
}

class B {

    private String name;

    @Autowired // Here we are injecting instance of Class A into class B so that you can use 'a' for accessing A's instance variables and methods.
    A a;

    // With setter and getter method

    public void showDetail() {
        System.out.println("Value of id form A class" + a.getId(););
    }
}

10
এটি সংকলন করবে না এবং সাধারণত ভুল। @Autowiredএর অর্থ এই নয় যে "আপনি Bক্লাস থেকে ক্লাসে সমস্ত ফাংশন (পদ্ধতি) এবং পরিবর্তনশীল ব্যবহার করতে পারেন A"। এটি কী হয় একটি দৃষ্টান্ত এনেছে Aদৃষ্টান্ত মধ্যে B, তাই আপনি কি করতে পারেন a.getId()থেকে B
দিমিত্রি মিনকভস্কি

@dimadima সুতরাং যদি তিনি System.out.println ("আইডির রূপের মান একটি শ্রেণি" + a.getId ()) করেন; এবং তিনি বাস্তবে যেমন করেন তবে এটি আরও সঠিক হবে। দয়া করে উত্তর দিন, কারণ এটি আমার কাছে স্বজ্ঞাতভাবে স্পষ্ট এবং আমার বর্তমান স্তরের বোধগম্যতা অনুসারে অটোয়ারিংয়ের ব্যাখ্যা দিচ্ছে।
জন দো

স্বতঃপ্রযুক্ত টীকাগুলি বসন্ত 2.5 ডক্স.স্প্রিং.আইও
ডকস /

1
আমি আরও নতুন হিসাবে আন্ডারস্টাডিনের জন্য, কি স্বয়ংক্রিয়ভাবে ডিফল্ট কনস্ট্রাক্টর ব্যবহার করে ক্লাস এ ক্লাসটি ইনস্ট্যান্ট করবে? যদি তা না হয় তবে কীভাবে মানগুলি বীন বা পরিষেবায় ইনস্ট্যান্ট হয়ে যায় যদি আমরা স্বতঃযুক্ত ব্যবহার করি। আমার ধারণা, এটি যদি ডিফল্ট কনস্ট্রাক্টর বলে, তবে কেন প্রথম স্থানে অটোওয়্যারিং ব্যবহার করুন, কেবল একটি এ = নতুন এ () করুন। পরিষ্কার করে বলো?
সমীর

@ সমীর নির্ভরতা স্বীকার করে আপনি নিজের ইউনিট টেস্টে প্রচুর বয়লারপ্লেট কোড এবং কন্ট্রোলার, পরিষেবা এবং দাও ক্লাসগুলি সংরক্ষণ করতে পারেন কারণ ক্ষেত্রগুলির ইনস্ট্যান্টেশনটি স্বয়ংক্রিয়ভাবে এটির সাথে আসে। কনস্ট্রাক্টরকে কল করার দরকার নেই।
কিলটেক

9

কি করে @Autowiredঅভ্যন্তরীণভাবে কাজ করে?

উদাহরণ:

class EnglishGreeting {
   private Greeting greeting;
   //setter and getter
}

class Greeting {
   private String message;
   //setter and getter
}

.xML ফাইল এটি ব্যবহার না করলে একরকম দেখাবে @Autowired :

<bean id="englishGreeting" class="com.bean.EnglishGreeting">
   <property name="greeting" ref="greeting"/>
</bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

আপনি যদি ব্যবহার করছেন @Autowired তবে:

class EnglishGreeting {
   @Autowired //so automatically based on the name it will identify the bean and inject.
   private Greeting greeting;
   //setter and getter
}

.xML ফাইল এটি ব্যবহার না করলে একরকম দেখাবে @Autowired :

<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

যদি এখনও কিছু সন্দেহ থাকে তবে নীচে লাইভ ডেমোটি দিয়ে যান

@ অটোভায়ার্ড কীভাবে অভ্যন্তরীণভাবে কাজ করে?


6

আপনাকে কেবল টীকা সহ আপনার পরিষেবা শ্রেণিকে টিকিয়ে দেওয়া দরকার UserServiceImpl:

@Service("userService")

বসন্তের ধারক পরিষেবা হিসাবে নিবন্ধিত হওয়ার সাথে সাথে এই শ্রেণীর জীবনচক্রটির যত্ন নেবে।

তারপরে আপনার কন্ট্রোলারে আপনি এটিকে তারের (তাত্ক্ষণিক) স্বয়ংক্রিয়ভাবে করতে পারেন এবং এর কার্যকারিতাটি ব্যবহার করতে পারেন:

@Autowired
UserService userService;

3

বসন্ত নির্ভরতা ইনজেকশন আপনাকে আপনার ক্লাস থেকে মিলিতকরণ সরাতে সহায়তা করে। এটির মতো বস্তু তৈরির পরিবর্তে:

UserService userService = new UserServiceImpl();

আপনি ডিআই প্রবর্তনের পরে এটি ব্যবহার করবেন:

@Autowired
private UserService userService;

এটি অর্জনের জন্য আপনার ServiceConfigurationফাইলে আপনার পরিষেবার একটি বিন তৈরি করতে হবে। এর পরে ServiceConfigurationআপনার সেই ক্লাসটি আপনার WebApplicationConfigurationক্লাসে আমদানি করা দরকার যাতে আপনি সেই শিমটি নিজের কন্ট্রোলারে এভাবে চালিত করতে পারেন:

public class AccController {

    @Autowired
    private UserService userService;
} 

আপনি এখানে জাভা কনফিগারেশন ভিত্তিক পিওসি পেতে পারেন উদাহরণটি


1

মানক উপায়:

@RestController
public class Main {
    UserService userService;

    public Main(){
        userService = new UserServiceImpl();
    }

    @GetMapping("/")
    public String index(){
        return userService.print("Example test");
    }
}

ব্যবহারকারী পরিষেবা ইন্টারফেস:

public interface UserService {
    String print(String text);
}

ইউজার সার্ভিসআইএমপিএল ক্লাস:

public class UserServiceImpl implements UserService {
    @Override
    public String print(String text) {
        return text + " UserServiceImpl";
    }
}

আউটপুট: Example test UserServiceImpl

এটি টাইট কাপল ক্লাসের একটি দুর্দান্ত উদাহরণ, খারাপ ডিজাইনের উদাহরণ এবং টেস্টিংয়ের সাথে সমস্যা হবে (পাওয়ারমোকিটোও খারাপ)।

এখন আসুন স্প্রিংবুট নির্ভরতা ইনজেকশনটি দেখুন, আলগা সংযোগের দুর্দান্ত উদাহরণ:

ইন্টারফেস একই থাকে,

প্রধান শ্রেণি:

@RestController
public class Main {
    UserService userService;

    @Autowired
    public Main(UserService userService){
        this.userService = userService;
    }

    @GetMapping("/")
    public String index(){
        return userService.print("Example test");
    }
}

সার্ভিস ইউজারআইএমপিএল ক্লাস:

@Component
public class UserServiceImpl implements UserService {
    @Override
    public String print(String text) {
        return text + " UserServiceImpl";
    }
}

আউটপুট: Example test UserServiceImpl

এবং এখন পরীক্ষা লিখতে সহজ:

@RunWith(MockitoJUnitRunner.class)
public class MainTest {
    @Mock
    UserService userService;

    @Test
    public void indexTest() {
        when(userService.print("Example test")).thenReturn("Example test UserServiceImpl");

        String result = new Main(userService).index();

        assertEquals(result, "Example test UserServiceImpl");
    }
}

আমি @Autowiredকন্সট্রাক্টর এ টীকাগুলি দেখিয়েছি তবে এটি সেটার বা ফিল্ডেও ব্যবহার করা যেতে পারে।


0

নিয়ন্ত্রণের বিপরীতকরণের সম্পূর্ণ ধারণাটির অর্থ আপনি নিজে হাতে বস্তুগুলি ইনস্ট্যান্ট করতে এবং সমস্ত প্রয়োজনীয় নির্ভরতা সরবরাহ করার জন্য কাজকর্ম থেকে মুক্ত। আপনি যখন উপযুক্ত টীকা সহ ক্লাস টিকা দেবেন (উদাঃ @Service) স্প্রিং স্বয়ংক্রিয়ভাবে আপনার জন্য অবজেক্টটি ইনস্ট্যান্ট করবে। আপনি যদি টীকাগুলির সাথে পরিচিত না হন তবে আপনি এর পরিবর্তে এক্সএমএল ফাইলও ব্যবহার করতে পারেন। তবে newআপনি যখন পুরো বসন্তের প্রসঙ্গটি লোড করতে চান না তখন ইউনিট পরীক্ষায় ম্যানুয়ালি ( কীওয়ার্ড সহ) ক্লাস ইনস্ট্যান্ট করা কোনও খারাপ ধারণা নয়।


0

মনে রাখবেন যে আপনার অবশ্যই স্প্রিং কনফিগারেশন ফাইলে @Autowiredউপাদান যুক্ত করে টীকাটি সক্ষম করতে হবে <context:annotation-config/>। এটি AutowiredAnnotationBeanPostProcessorএনটোটেশন প্রক্রিয়াজাতকরণের যত্ন নেওয়ার ক্ষেত্রে নিবন্ধভুক্ত করবে ।

এবং তারপরে আপনি ক্ষেত্রের ইনজেকশন পদ্ধতিটি ব্যবহার করে আপনার পরিষেবাকে অটোয়ার করতে পারেন।

public class YourController{

 @Autowired
 private UserService userService; 

}

আমি স্প্রিংয়ের @ অটোভায়ার্ড টীকাগুলি পোস্ট থেকে এটি পেয়েছি


0

3 টি উপায় রয়েছে যা আপনি ব্যবহার করে একটি উদাহরণ তৈরি করতে পারেন @Autowired

1. সম্পত্তি @Autowiredউপর

টীকাগুলি সরাসরি সম্পত্তিগুলিতে ব্যবহার করা যেতে পারে, সুতরাং গ্রাহকগণ এবং সেটটারগুলির প্রয়োজনীয়তা দূর করে:

    @Component("userService")
    public class UserService {

        public String getName() {
            return "service name";
        }
    }

    @Component
    public class UserController {

        @Autowired
        UserService userService

    }

উপরের উদাহরণে, বসন্ত userServiceকখন সন্ধান করে এবং ইনজেকশন দেয়UserController তৈরি হয় তা সন্ধান করে ।

2. @Autowiredসেটারগুলিতে

@Autowiredটীকা সেটার পদ্ধতি উপর ব্যবহার করা যাবে। নীচের উদাহরণে, যখন টীকা সেটার পদ্ধতির উপর ব্যবহার করা হয়, সেটার পদ্ধতির নিদর্শনের সঙ্গে বলা হয় userServiceযখন UserControllerতৈরি করা হয়:

public class UserController {

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
            this.userService = userService;
    }
}

3. @Autowiredনির্মাণকারী উপর

@Autowiredটীকা এছাড়াও কনস্ট্রাকটর ব্যবহার করা যেতে পারে। নীচের উদাহরণে, যখন কনস্ট্রাক্টারে টীকা ব্যবহার করা userServiceহয়, তৈরির সময় কনস্ট্রাক্টরের একটি আর্গুমেন্ট হিসাবে একটি উদাহরণ সংযোজন করা UserControllerহয়:

public class UserController {

    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService= userService;
    }
}

0

সরল কথায় অটোওয়াইরিং, ওয়্যারিংগুলি স্বয়ংক্রিয়ভাবে লিঙ্ক হয়, এখন প্রশ্ন আসে কে এই কাজ করে এবং কোন ধরণের ওয়্যারিং করে। উত্তরটি: কনটেইনার এটি করে এবং দ্বিতীয় ধরণের ওয়্যারিং সমর্থনযোগ্য, আদিম পদক্ষেপগুলি ম্যানুয়ালি করা দরকার।

প্রশ্ন: ধারক কীভাবে তারের ধরণের জানতে পারে?

উত্তর: আমরা এটিকে বাই টাইপ, বাই নাম, কনস্ট্রাক্টর হিসাবে সংজ্ঞায়িত করি।

প্রশ্ন: আমরা কীভাবে অটোওয়্যারিংয়ের ধরণটি সংজ্ঞায়িত করি না?

উত্তর: হ্যাঁ, এটি এখানে অ্যানোটেশন দেওয়া হয়েছে, @ অটোভায়ার্ড।

প্রশ্ন: তবে কীভাবে সিস্টেম জানে, আমার এই জাতীয় মাধ্যমিক ডেটা বাছাই করা উচিত?

উত্তর: আপনি সেই তথ্যটি আপনার স্প্রিং.এক্সএমএল ফাইলে সরবরাহ করবেন বা আপনার ক্লাসে স্টেরোটাইপ টীকাগুলি ব্যবহার করবেন যাতে ধারকরা নিজেরাই আপনার জন্য বস্তু তৈরি করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.