2012-03-09 14 views
24

मैं निम्नलिखित वसंत विन्यास है:स्प्रिंग autowired सेम रिक्त है

@Aspect 
public class SyncLoggingAspect { 
    @Autowired 
    private SimpleEmailSender simpleEmailSender 

    @AfterReturning(value="execution(* uk.co.mysite.datasync.polling.Poller+.doPoll())", returning="pusher") 
    public void afterPoll(Pusher pusher) {  
     simpleEmailSender.send(new PusherEmail(pusher)); 
    } 
} 

इस पहलू काम करता है (मैं afterPoll पर एक ब्रेकपाइंट हिट कर सकते हैं:

<context:component-scan base-package="uk.co.mysite.googlecontactsync.aop"/> 

<bean name="simpleEmailSender" class="uk.co.mysite.util.email.simple.SimpleEmailSenderImplementation"/> 

<aop:aspectj-autoproxy/> 

तो मैं एक पहलू है) लेकिन simpleEmailSender शून्य है। दुर्भाग्य से मुझे स्पष्ट दस्तावेज नहीं मिल रहा है कि यह क्यों है। (रिकॉर्ड के लिए, मेरे simpleEmailSender सेम मौजूद है और सही ढंग से अन्य वर्गों में तार किया जाता है) निम्नलिखित बातें मुझे भ्रमित:

  1. संदर्भ है: घटक स्कैन @Aspect उठा होना चाहिए? यदि यह निश्चित रूप से एक वसंत प्रबंधित बीन होगा, तो इस प्रकार स्वायत्त काम करना चाहिए?
  2. यदि संदर्भ: घटक-स्कैन पहलुओं को बनाने के लिए नहीं है, तो मेरा पहलू कैसे बनाया जा रहा है? मैंने सोचा था कि एओपी: पहलू-ऑटोप्रोक्सी सिर्फ मेरी @ एस्पेक्ट क्लास प्रॉक्सी करने के लिए एक बीनपोस्टप्रोसेसर बनाता है? यह कैसे होगा यदि यह वसंत प्रबंधित बीन नहीं है?

स्पष्ट रूप से आप बता सकते हैं कि मुझे समझ में नहीं आता कि चीजों को जमीन से कैसे काम करना चाहिए।

+2

आप भी 'जोड़ सकते हैं @ Service' अगले' करने के लिए @ Aspect'? –

+1

यह अभी भी शून्य है, लेकिन अब मुझे जानकारी मिलती है: org.s[email protected]76faf7d6 में पूर्व-तत्काल सिंगलेट्स: परिभाषित बीन्स [..., सिंकलॉगिंग लॉग इन – mogronalol

+0

क्या आपने एक सेटर जोड़ने का प्रयास किया था SimpleEmailSender ?? – Rocky

उत्तर

29

पहलू एक सिंगलटन ऑब्जेक्ट है और स्प्रिंग कंटेनर के बाहर बनाया गया है। एक्सएमएल कॉन्फ़िगरेशन के साथ एक समाधान पहलू को पुनः प्राप्त करने के लिए स्प्रिंग की फैक्ट्री विधि का उपयोग करना है।

<bean id="syncLoggingAspect" class="uk.co.demo.SyncLoggingAspect" 
    factory-method="aspectOf" /> 

इस कॉन्फ़िगरेशन के साथ पहलू को किसी भी अन्य वसंत बीन के रूप में माना जाएगा और ऑटोवायरिंग सामान्य के रूप में काम करेगी।

आपको वसंत कंटेनर के बाहर बनाए गए कन्स्ट्रक्टर या ऑब्जेक्ट्स के बिना एनम ऑब्जेक्ट्स और अन्य ऑब्जेक्ट्स पर फ़ैक्टरी-विधि का भी उपयोग करना होगा।

+5

यह तब होता है जब आप AspectJ का उपयोग कर रहे हैं। मुझे वसंत एओपी का उपयोग करना चाहिए। क्या मेरे कॉन्फ़िगरेशन में कुछ ऐसा है जो मुझे इस मामले को जोड़ने के लिए गायब/जोड़ने की ज़रूरत है? – mogronalol

+2

इसे आज़माने के बाद आपने वास्तव में मुझे समाधान दिया है, लेकिन अब मैं अभी भी उलझन में हूं क्योंकि मेरे उपरोक्त बिंदु – mogronalol

+0

वसंत दस्तावेज़ भारी है। विन्यास योग्य गैर सिंगलेट्स के लिए है। – lwpro2

17

एक और विकल्प एक्सएमएल के साथ गड़बड़ करने की बजाय @Configurable को अपने पहलू वर्ग में जोड़ना है।

+2

अच्छा। एक्सएमएल में <संदर्भ: वसंत-कॉन्फ़िगर /> याद रखें। –

+0

धन्यवाद! '@ कॉन्फ़िगर करने योग्य 'ने मेरे लिए चाल बनाई। '@ कॉन्फ़िगर करने योग्य' एनोटेशन के साथ किसी भी अलग JavaConfig या XML फैक्ट्री-विधि = 'पहलू-के' की आवश्यकता नहीं है। –

+0

मुझे अभी एक ऐसी स्थिति का सामना करना पड़ा है जहां यह विफल हो जाता है; जब वसंत संदर्भ ताज़ा होता है, वसंत स्वचालित रूप से संदर्भों को अद्यतन नहीं करता है। मैंने इस समस्या का हल ढूंढने के लिए http://stackoverflow.com/q/22826526/827480 पर एक प्रश्न पोस्ट किया है। –

2

यह blog post यह वास्तव में अच्छी तरह से बताता है। इस तथ्य के कारण है कि पहलू सिंगलटन वसंत कंटेनर के बाहर बनाई गई है आप कारखाने में विधि = "aspectof" उस ही उपलब्ध है के बाद यह AspectJ द्वारा में बुना जाता है उपयोग करने की आवश्यकता होगी (नहीं स्प्रिंग AOP):

सूचना कारखाना -method = "aspectOf" जो इस बीन को बनाने के लिए वसंत को वास्तविक AspectJ (स्प्रिंग एओपी नहीं) पहलू का उपयोग करने के लिए कहता है। ताकि के बाद पहलू में बुना हुआ "aspectOf" विधि हो।

ताकि:

कोई मिलती-जुलती कारखाने विधि पाया: कारखाने विधि 'aspectof()' - मतलब यह होगा कि पहलू AspectJ बुनकर से बुना नहीं किया गया।

वसंत 3.1 के साथ अपने अनुभव से, यदि मैं निर्भरता इंजेक्शन के लिए @Autowired लेकिन पारंपरिक सेटटर का उपयोग नहीं करता, तो यह इंजेक्शन और पहलू जे वीवर के बिना अपेक्षित काम करता है। हालांकि मुझे सिंगलटन होने के पहलू के साथ समस्याएं आ रही हैं ... इसका परिणाम 'पर्थिस' तत्काल मॉडल में होता है। ।

4

जावा कॉन्फ़िगरेशन के साथ @Autowired को कॉन्फ़िगर करना (इसलिए कोई एक्सएमएल आधारित कॉन्फ़िगरेशन) को कक्षा में @Configuration जोड़ने से थोड़ा अतिरिक्त काम की आवश्यकता है, क्योंकि इसे पहलू की विधि भी चाहिए।

क्या मेरे लिए काम किया एक नया वर्ग पैदा किया गया था:

@Component 
public class SpringApplicationContextHolder implements ApplicationContextAware { 

    private static ApplicationContext applicationContext = null; 

    public static ApplicationContext getApplicationContext() { 
     return applicationContext; 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     this.applicationContext = applicationContext; 
    } 
} 

और फिर @DependsOn @Configured और @Autowired उपयोग करने के साथ संयोजन के रूप में उपयोग करते हैं कि आप पहलू में:

@DependsOn("springApplicationContextHolder") 
@Configuration 
@Aspect 
public class SomeAspect { 

    @Autowired 
    private SomeBean someBean; 

    public static SomeAspect aspectOf() { 
     return SpringApplicationContextProvider.getApplicationContext().getBean(SomeAspect.class); 
    } 

@DependsOn है आवश्यक है क्योंकि वसंत निर्भरता निर्धारित नहीं कर सकता क्योंकि बीन स्थिर रूप से उपयोग किया जाता है।

+0

इसके लिए धन्यवाद क्योंकि यह एकमात्र एनोटेशन आधारित उदाहरण था जिसे मैं पा सकता था। – mag382

+0

CheckServicesPermissionsAspect.class? मुझे समझ में नहीं आता कि यह क्या है। – sudeepdino008

+0

यह एक मौजूदा प्रोजेक्ट से एक प्रति था, लेकिन मैं उस बिट को सामान्यीकृत करना भूल गया था, अब तय किया गया है :) – Wouter

1

पहलू वर्ग में @ कॉम्पोनेंट जोड़ें और आपकी निर्भरताओं को स्वचालित रूप से इंजेक्शन दिया जाना चाहिए। और संदर्भ जोड़ें: पैकेज के लिए घटक-स्कैन जहां आपका पहलू वसंत संदर्भ फ़ाइल में है।

@Component 
@Aspect 
public class SomeAspect { 
    /* following dependency should get injected */ 
    @Autowired 
    SomeTask someTask; 
    /* rest of code */ 
} 
+1

यह वास्तव में मेरे लिए काम किया। – dantebarba

4

मैं 50 प्रतिनिधि इसलिए यहाँ एक सवाल पर टिप्पणी करने से @ Jitendra Vispute जवाब से संबंधित एक और जवाब है नहीं है। आधिकारिक स्प्रिंग दस्तावेज़ का उल्लेख है:

आप अपने स्प्रिंग एक्सएमएल विन्यास में नियमित रूप से सेम के रूप में पहलू कक्षाएं रजिस्टर या classpath स्कैनिंग के माध्यम से उन्हें स्वतः खोजें सकता है - किसी भी अन्य वसंत से प्रबंधित सेम की तरह। हालांकि, ध्यान दें कि @Aspect एनोटेशन क्लासपाथ में ऑटोडेटेक्शन के लिए पर्याप्त नहीं है: उस उद्देश्य के लिए, आपको स्प्रिंग के घटक स्कैनर के नियमों के अनुसार एक अलग @ कॉम्पोनेंट एनोटेशन (या वैकल्पिक रूप से एक कस्टम स्टीरियोटाइप एनोटेशन जो योग्यता प्राप्त करने की आवश्यकता है) जोड़ना होगा। Source: Spring '4.1.7.Release' documentation

इसका मतलब यह होगा एक @Component एनोटेशन जोड़ने और अपने विन्यास पर @ComponentScan जोड़ने @Jitendra Vispute के उदाहरण का काम करते हैं कि। वसंत बूट एओपी नमूने के लिए यह काम किया, हालांकि मैं संदर्भ ताज़ा करने के साथ गड़बड़ नहीं किया था। Spring boot aop sample:

आवेदन:

package sample.aop; 
@SpringBootApplication 
public class SampleAopApplication implements CommandLineRunner { 
    // Simple example shows how an application can spy on itself with AOP 
    @Autowired 
    private HelloWorldService helloWorldService; 
    @Override 
    public void run(String... args) { 
     System.out.println(this.helloWorldService.getHelloMessage()); 
    } 
    public static void main(String[] args) throws Exception { 
     SpringApplication.run(SampleAopApplication.class, args); 
    } 
} 

आवेदन भी @SpringBootApplication के बजाय निम्नलिखित एनोटेशन के साथ के रूप में सादे स्प्रिंग फ्रेमवर्क आवेदन चलाना चाहिए:

  • @Configuration
  • @EnableAspectJAutoProxy
  • @ कॉम्पोनेंटस्कैन

और SpringAplication के बजाय एक एनोटेशन कॉन्फिग एप्प्लिकेशन कॉन्टेक्स्ट।

सेवा:

package sample.aop.service; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.stereotype.Component; 
@Component 
public class HelloWorldService { 
    @Value("${name:World}") 
    private String name; 
    public String getHelloMessage() { 
     return "Hello " + this.name; 
    } 
} 

मॉनिटर पहलू:

package sample.aop.monitor; 
import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.AfterReturning; 
import org.aspectj.lang.annotation.Aspect; 
import org.springframework.stereotype.Component; 
@Aspect 
@Component 
public class ServiceMonitor { 
    @AfterReturning("execution(* sample..*Service.*(..))") 
    public void logServiceAccess(JoinPoint joinPoint) { 
     System.out.println("Completed: " + joinPoint); 
    } 
} 
0

उपयोग समय बुनाई संकलन, उदाहरण प्लगइन पर के लिए देखें: https://github.com/avner-levy/minimal_spring_hibernate_maven_setup/blob/master/pom.xml

एनोटेशन और वसंत के निम्नलिखित संयोजन मेरे लिए कॉन्फ़िगर काम करता है टोबी द्वारा उपरोक्त नोट्स के लिए धन्यवाद के रूप में/विली/एरिक:

कक्षा:

package com.abc 
@Configurable 
@Aspect 
public class MyAspect { 
    @Autowired 
    protected SomeType someAutoWiredField; 
} 

एक्सएमएल:

<context:spring-configured /> 
<context:component-scan base-package="com.abc" /> 
2

स्प्रिंग बूट @Autowired AspectJ साथ मैं निम्न विधि पाया है का उपयोग करने के लिए। विन्यास कक्षा में अपने पहलू जोड़ें:

@Configuration 
@ComponentScan("com.kirillch.eqrul") 
public class AspectConfig { 

    @Bean 
    public EmailAspect theAspect() { 
     EmailAspect aspect = Aspects.aspectOf(EmailAspect.class); 
     return aspect; 
    } 

} 

तो फिर तुम सफलतापूर्वक अपने पहलू वर्ग में अपनी सेवाओं को autowire कर सकते हैं:

@Aspect 
public class EmailAspect { 

    @Autowired 
    EmailService emailService; 
संबंधित मुद्दे