একই ইন্টারফেস প্রয়োগকারী দুটি মটরশুটি স্বীকৃত - কীভাবে ডিফল্ট শিমটি অটোয়ারে সেট করবেন?


138

পটভূমি:

আমার একটি স্প্রিং 2.5 / জাভা / টমক্যাট অ্যাপ্লিকেশন রয়েছে। নিম্নলিখিত শিমটি রয়েছে, যা অ্যাপ্লিকেশন জুড়ে অনেক জায়গায় ব্যবহৃত হয়

public class HibernateDeviceDao implements DeviceDao

এবং নিম্নলিখিত শিমটি নতুন:

public class JdbcDeviceDao implements DeviceDao

প্রথম শিমটি তাই কনফিগার করা হয়েছে (প্যাকেজের সমস্ত মটরশুটি অন্তর্ভুক্ত করা হয়েছে)

<context:component-scan base-package="com.initech.service.dao.hibernate" />

দ্বিতীয় (নতুন) শিম আলাদাভাবে কনফিগার করা হয়েছে

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
    <property name="dataSource" ref="jdbcDataSource">
</bean>

এই ফলাফলটি (অবশ্যই) সার্ভারটি শুরু করার সময় একটি ব্যতিক্রমে:

নেস্টেড ব্যতিক্রমটি org.springframework.beans.factory.NoSuchBeanDefinitionException: প্রকারের কোনও অনন্য বিন [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] সংজ্ঞায়িত করা হয়নি: প্রত্যাশিত একক মেলা শিম কিন্তু পাওয়া গেছে 2: [ডিভাইস ডেও, জেডিবিসিডিভ

একটি শ্রেণীর কাছ থেকে শিমটি এভাবে চালিত হওয়ার চেষ্টা করছে

@Autowired
private DeviceDao hibernateDevicDao;

কারণ একই ইন্টারফেস প্রয়োগকারী দুটি মটরশুটি রয়েছে।

প্রশ্নটি:

মটরশুটিটি কনফিগার করা কি সম্ভব

১. বিদ্যমান ক্লাসগুলিতে আমাকে কোনও পরিবর্তন করতে হবে না, যা ইতিমধ্যে HibernateDeviceDaoস্বশিক্ষিত রয়েছে

২. এখনও দ্বিতীয় (নতুন) শিমটি এভাবে ব্যবহার করতে সক্ষম হচ্ছে:

@Autowired
@Qualifier("jdbcDeviceDao")

HibernateDeviceDaoযেমন, আমি শিমটি ডিফল্ট শিমটি স্বাবরক্ষিত হওয়ার জন্য কনফিগার করার একটি উপায়ের প্রয়োজন হবে, একই সাথে টীকাটির JdbcDeviceDaoসাথে নির্দিষ্ট করে নির্দিষ্ট করার সময় এর ব্যবহারের অনুমতি দেয় @Qualifier

আমি ইতিমধ্যে যা চেষ্টা করেছি:

আমি সম্পত্তি সেট করার চেষ্টা করেছি

autowire-candidate="false"

জেডিবিসি ডিভাইসডাওর জন্য বিন বিন্যাসে:

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
    <property name="dataSource" ref="jdbcDataSource"/>
</bean>

কারণ স্প্রিং ডকুমেন্টেশন বলে যে

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

যার অর্থ আমি ব্যাখ্যা করেছি যে আমি এখনও টীকাটি JdbcDeviceDaoব্যবহার করে স্বায়ত্তশাসন করতে পেরেছিলাম @Qualifierএবং HibernateDeviceDaoডিফল্ট বিন হিসাবে থাকতে পারি । স্পষ্টতই আমার ব্যাখ্যাটি সঠিক ছিল না, যদিও সার্ভারটি শুরু করার সময় নিম্নলিখিত ত্রুটি বার্তায় এর ফলস্বরূপ:

প্রকারের অসন্তুষ্ট নির্ভরতা [শ্রেণি com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: প্রত্যাশিত কমপক্ষে 1 টি মেলা শিম

আমি যে ক্লিনিকে কোয়ালিফায়ার দিয়ে সিমকে চালিত করার চেষ্টা করেছি সেখান থেকে আসছি:

@Autowired
@Qualifier("jdbcDeviceDao")

সমাধান:

@ রিসোর্স টীকাটি ব্যবহারের চেষ্টা করার জন্য স্কাফম্যানের পরামর্শ । সুতরাং কনফিগারেশনে অটোয়ার-প্রার্থী jdbcDeviceDao এর জন্য মিথ্যা হিসাবে সেট হয়ে গেছে এবং jdbcDeviceDao ব্যবহার করার সময় আমি @ রিসোর্স টিকা (@ কোয়ালিফায়ারের পরিবর্তে) ব্যবহার করে এটি উল্লেখ করি:

@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;

আমি যদি কোডটির 100 টি জায়গায় এই ইন্টারফেসটি ব্যবহার করি এবং আমি সমস্ত স্থানে অন্য কোথাও কোয়ালিফায়ার বা রিসোর্স টীকা পরিবর্তন করতে চাই না তবে অন্য প্রয়োগের দিকে যেতে চাই। এবং আমি বাস্তবায়নের কোডও পরিবর্তন করতে চাই না। গুইসের মতো সুস্পষ্ট বাধ্যবাধকতা কেন নেই?
ড্যানিয়েল হুরি

উত্তর:


134

আমি হাইবারনেট ডিএও ক্লাসটি চিহ্নিত করার পরামর্শ দিচ্ছি @Primary(যেমন ধরে নিই যে আপনি ব্যবহার @Repositoryকরেছেন HibernateDeviceDao):

@Primary
@Repository
public class HibernateDeviceDao implements DeviceDao

autowire-candidateঅন্য শিমের কোনও প্রয়োজন ছাড়াই এটি ডিফল্ট অটোয়ার ক্যান্ডিডেটেট হিসাবে নির্বাচন করা হবে ।

এছাড়াও, ব্যবহার না করে @Autowired @Qualifier, আমি @Resourceনির্দিষ্ট মটরশুটি বাছাইয়ের জন্য এটি ব্যবহার করতে আরও মার্জিত বলে মনে করি

@Resource(name="jdbcDeviceDao")
DeviceDao deviceDao;

আমি প্রশ্নটিতে উল্লেখ করতে ভুলে গেছি যে আমি স্প্রিং 2.5 ব্যবহার করছি (এখন আমি প্রশ্নটি সম্পাদনা করেছি) সুতরাং @ প্রাইমারি কোনও বিকল্প নয়।
সাইমন

1
@ সিমন: হ্যাঁ, এটি বরং গুরুত্বপূর্ণ ছিল। ব্যবহার করে দেখুন @Resourceযেমন আমিও প্রস্তাব, টীকা।
স্কাফম্যান

1
ধন্যবাদ, রিসোর্স টীকাটি সমস্যাটি সমাধান করেছে - এখন অটোয়ার-প্রার্থী সম্পত্তি আমার প্রত্যাশা অনুযায়ী কাজ করে।
সাইমন

ধন্যবাদ! মাধ্যমে শিম নাম উল্লেখ মধ্যে পার্থক্য কি @Resourceএবং @Qualifierপৃথক্ যে সাবেক পরেরটির তুলনায় অপেক্ষাকৃত নতুন থেকে?
asgs

1
@ এসএসজিগুলি রিসোর্স টিকা ব্যবহার করে জিনিসগুলি সহজ করে। স্বতঃ / কোয়ালিফায়ার কম্বো না রেখে আপনি এটিকে নির্ভরতা ইনজেকশনের জন্য চিহ্নিত করতে পারেন এবং নামটি একটি লাইনে নির্দিষ্ট করতে পারেন। নোট করুন যে সিমনের সমাধানটি অতিরিক্ত কাজ নয়, স্বতঃশক্তিযুক্ত টিকা মুছে ফেলা যায়।
গিলবার্ট অ্যারেনাস ড্যাজার 21

37

কি হবে @Primary?

ইঙ্গিত করে যে একাধিক প্রার্থী যখন একক মূল্যবান নির্ভরতা নির্ভর করতে সক্ষম হয় তখন একটি শিমকে অগ্রাধিকার দেওয়া উচিত । প্রার্থীদের মধ্যে ঠিক যদি একটি 'প্রাথমিক' শিম উপস্থিত থাকে তবে এটি স্বয়ংক্রিয় মান হবে। এই টীকাটি স্প্রিং এক্সএমএলে <bean>উপাদানটির গুণকের সমার্থক equivalentprimary

@Primary
public class HibernateDeviceDao implements DeviceDao

অথবা আপনি যদি চান যে আপনার জেডিবিসি সংস্করণটি ডিফল্টরূপে ব্যবহার করা যায়:

<bean id="jdbcDeviceDao" primary="true" class="com.initech.service.dao.jdbc.JdbcDeviceDao">

@Primary ইন্টিগ্রেশন টেস্টিংয়ের জন্যও দুর্দান্ত এটি যখন আপনি সহজেই ডেকে আনা সংস্করণ দ্বারা স্টাব্বড সংস্করণ দিয়ে উত্পাদন শিমটি সহজেই প্রতিস্থাপন করতে পারেন।


আমি প্রশ্নটিতে উল্লেখ করতে ভুলে গেছি যে আমি স্প্রিং 2.5 ব্যবহার করছি (এখন আমি প্রশ্নটি সম্পাদনা করেছি) সুতরাং @ প্রাইমারি কোনও বিকল্প নয়।
সাইমন

1
@ সিমন: আমি বিশ্বাস করি primary=""বৈশিষ্ট্যটি আগে পাওয়া যায়। কেবল HibernateDeviceDaoএক্সএমএলে ঘোষণা করুন এবং এটি উপাদান / টিকা স্ক্যান থেকে বাদ দিন।
টমাসজ নুরকিউইচ

1
ডকুমেন্টেশন মতে এটা 3.0 থেকে উপলব্ধ: static.springsource.org/spring/docs/3.1.x/javadoc-api/org/... ভাল টিপ যাই হোক, আমি পরের প্রকল্পের জন্য প্রাথমিক টীকা মনে রাখতে হবে যখন আমি সক্ষম নই স্প্রিং 3.x ব্যবহার করতে
সাইমন

8

বসন্ত 2.5 এর জন্য, এখানে নেই @Primary। একমাত্র উপায় হ'ল ব্যবহার করা @Qualifier


2
The use of @Qualifier will solve the issue.
Explained as below example : 
public interface PersonType {} // MasterInterface

@Component(value="1.2") 
public class Person implements  PersonType { //Bean implementing the interface
@Qualifier("1.2")
    public void setPerson(PersonType person) {
        this.person = person;
    }
}

@Component(value="1.5")
public class NewPerson implements  PersonType { 
@Qualifier("1.5")
    public void setNewPerson(PersonType newPerson) {
        this.newPerson = newPerson;
    }
}

Now get the application context object in any component class :

Object obj= BeanFactoryAnnotationUtils.qualifiedBeanOfType((ctx).getAutowireCapableBeanFactory(), PersonType.class, type);//type is the qualifier id

you can the object of class of which qualifier id is passed.

0

@ রিসোর্স (নাম = "{আপনার শিশু শ্রেণীর নাম}") কাজ করার কারণ কিন্তু @ স্বীকৃত মাঝে মাঝে কাজ করে না কারণ তাদের মিলনক্রমের ক্রমের পার্থক্য রয়েছে

@ অটোয়ার
টাইপ, বাছাইকারী , নাম মিলানোর ক্রম

@ রিসোর্সের
নাম, প্রকার, যোগ্যতার সাথে মিলের ক্রম

আরও বিশদ বিবরণ এখানে পাওয়া যাবে:
ইনজেকশন এবং রিসোর্স এবং স্বীকৃত টিকা

এই ক্ষেত্রে, পিতামাত্ত শ্রেণি বা ইন্টারফেস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত বিভিন্ন শিশু শ্রেণি @ অটোয়ারকে বিভ্রান্ত করে, কারণ তারা একই ধরণের; @ রিসোর্স হিসাবে নামটি প্রথম মিলের অগ্রাধিকার হিসাবে ব্যবহার করে, এটি কাজ করে।

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