এই প্রশ্নের উত্তর দেওয়া হওয়ার পরে বসন্ত বিশ্বে অনেক কিছুই পরিবর্তিত হয়েছে। স্প্রিং বর্তমান ব্যবহারকারীকে একটি নিয়ামক হিসাবে পাওয়া সহজ করেছে। অন্যান্য মটরশুটির জন্য, বসন্ত লেখকের পরামর্শ গ্রহণ করেছে এবং 'সিকিউরিটি কনটেক্সটহোল্ডার' এর ইনজেকশনটিকে সহজ করেছে। আরও বিস্তারিত মন্তব্য করা হয়।
এই সমাধানটি আমি শেষ করে শেষ করেছি। SecurityContextHolder
আমার নিয়ামকটি ব্যবহার করার পরিবর্তে , আমি এমন কিছু ইনজেকশান করতে চাই যা SecurityContextHolder
হুডের নীচে ব্যবহার করে তবে আমার কোড থেকে সেই সিঙ্গলটন-জাতীয় ক্লাসটি বিমূর্ত করে দেয়। আমার নিজের ইন্টারফেসটি ঘুরিয়ে দেওয়া ছাড়া এটি করার কোনও উপায় আমি খুঁজে পাইনি:
public interface SecurityContextFacade {
SecurityContext getContext();
void setContext(SecurityContext securityContext);
}
এখন, আমার নিয়ামক (বা যাই হোক POJO) এর মতো দেখতে পাবেন:
public class FooController {
private final SecurityContextFacade securityContextFacade;
public FooController(SecurityContextFacade securityContextFacade) {
this.securityContextFacade = securityContextFacade;
}
public void doSomething(){
SecurityContext context = securityContextFacade.getContext();
// do something w/ context
}
}
এবং, ইন্টারফেসটি ডিউপলিংয়ের বিন্দু হওয়ার কারণে, ইউনিট পরীক্ষাটি সোজা। এই উদাহরণে আমি মকিতো ব্যবহার করি:
public class FooControllerTest {
private FooController controller;
private SecurityContextFacade mockSecurityContextFacade;
private SecurityContext mockSecurityContext;
@Before
public void setUp() throws Exception {
mockSecurityContextFacade = mock(SecurityContextFacade.class);
mockSecurityContext = mock(SecurityContext.class);
stub(mockSecurityContextFacade.getContext()).toReturn(mockSecurityContext);
controller = new FooController(mockSecurityContextFacade);
}
@Test
public void testDoSomething() {
controller.doSomething();
verify(mockSecurityContextFacade).getContext();
}
}
ইন্টারফেসের ডিফল্ট বাস্তবায়নটি এরকম দেখাচ্ছে:
public class SecurityContextHolderFacade implements SecurityContextFacade {
public SecurityContext getContext() {
return SecurityContextHolder.getContext();
}
public void setContext(SecurityContext securityContext) {
SecurityContextHolder.setContext(securityContext);
}
}
এবং, অবশেষে, উত্পাদনের স্প্রিং কনফিগারেশনটি এর মতো দেখাচ্ছে:
<bean id="myController" class="com.foo.FooController">
...
<constructor-arg index="1">
<bean class="com.foo.SecurityContextHolderFacade">
</constructor-arg>
</bean>
কিছুটা নির্বোধের চেয়ে আরও বেশি মনে হয় যে স্প্রিং, সমস্ত জিনিসের নির্ভরতা ইনজেকশন ধারক, অনুরূপ কিছু ইনজেকশনের কোনও উপায় সরবরাহ করে নি। আমি বুঝতে পারি যে SecurityContextHolder
এসিজি থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছিল, তবে এখনও। বিষয়টি হ'ল এগুলি এতটা কাছাকাছি - SecurityContextHolder
অন্তর্নিহিত SecurityContextHolderStrategy
উদাহরণটি (যা একটি ইন্টারফেস) পাওয়ার জন্য যদি কেবল কোনও গেট থাকে তবে আপনি এটি ইনজেকশন করতে পারতেন। আসলে, আমি এমনকি জের ইস্যুটি খোলার জন্য।
একটি শেষ কথা - আমি এখানে আগে আমার দেওয়া উত্তরটি যথেষ্ট পরিমাণে পরিবর্তন করেছি। আপনি যদি কৌতূহলী হন তবে ইতিহাসটি যাচাই করুন তবে সহকর্মী যেমন আমাকে বলেছিলেন, আমার আগের উত্তরটি বহু-থ্রেডযুক্ত পরিবেশে কাজ করবে না। অন্তর্নিহিত SecurityContextHolderStrategy
ব্যবহৃত SecurityContextHolder
হয়, ডিফল্টরূপে, এর একটি উদাহরণ ThreadLocalSecurityContextHolderStrategy
, যা SecurityContext
এস এ সঞ্চয় করে ThreadLocal
। সুতরাং, SecurityContext
আরম্ভের সময় সরাসরি শিমের মধ্যে সরাসরি ইনজেক্ট করা ভাল ধারণা নয় - এটি ThreadLocal
প্রতিটি সময় থেকে বহু-থ্রেডযুক্ত পরিবেশে পুনরুদ্ধার করা প্রয়োজন, তাই সঠিকটি পুনরুদ্ধার করা হবে।