2012-04-18 9 views
11

मैं एक गेम इंजन/लाइब्रेरी लिख रहा हूं जिसमें मेरे पास एक ईवेंट प्रेषक वर्ग है जो "पंजीकृत" ईवेंट हैंडलर कक्षाओं के श्रोता विधियों को कॉल करके ईवेंट भेजता है। कोई उचित प्रेषक विधि को कॉल करके इवेंट हैंडलर/श्रोता को ईवेंट प्रेषक के साथ पंजीकृत कर सकता है।जावा क्लास w/इंस्ट्रुमेंटेशन में कोड जोड़ना: एएसएम या बीसीईएल?

यह स्पष्ट रूप से प्रत्येक ईवेंट हैंडलर (और मेरे इंजन के अन्य पहलुओं के समान बॉलीएरप्लेट कोड) के पंजीकरण के लिए कुछ बॉयलरप्लेट कोड की ओर जाता है, इसलिए मैं सोच रहा था - लोडिंग के दौरान सभी आवश्यक कोड में जोड़ने के लिए इंस्ट्रुमेंटेशन का उपयोग कैसे करें इवेंट हैंडलर क्लास का, ताकि कोड प्रेषण के दौरान ईवेंट प्रेषक के साथ कोई स्पष्ट पंजीकरण आवश्यक न हो - प्रोग्राम चलाए जाने पर प्रेषक की पंजीकरण विधि को कॉल स्वचालित रूप से जोड़ा जाता है।

यह मेरी समझ है कि इंस्ट्रुमेंटेशन का उपयोग करने के लिए किसी को कुछ बाइटकोड संशोधक एपीआई का उपयोग करना चाहिए। मैं दो - एएसएम और बीसीईएल के बारे में जानता हूं। मुझे किसका उपयोग करना चाहिए? जाहिर है, यह एक साधारण काम है जिसे मैं करने की कोशिश कर रहा हूं, इसलिए मैं वह सीखना चाहता हूं जो सीखना आसान और बेहतर दस्तावेज हो।

संपादित करें: यहां एक विशिष्ट उदाहरण है।

मूल ईवेंट हैंडलर वर्ग:

@Handler //indicates this this class should be transformed 
public class MouseEventHandler implements EventHandler<MouseEvent> 
{ 
    //hidden default constructor 
    public void handleEvent(MouseEvent event) 
    { ... } 
} 

परिवर्तन के बाद:

@Handler 
public class MouseEventHandler implements EventHandler<MouseEvent> 
{ 
    public MouseEventHandler() 
    { 
     //add this line of code to default constructor 
     Game.getEventDispatcher().addEventHandler(this); 
    } 
    public void handleEvent(MouseEvent event) 
    { ... } 
} 

उत्तर

20
  • एएसएम (http://asm.ow2.org/) तेजी से और सक्रिय रूप से
  • BCEL विकसित है (http://commons.apache.org/bcel/) अब अपेक्षाकृत धीमी गति से और है बनाए रखा
  • जावासिस्ट (http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/) शायद सबसे आसान के साथ अगर आप जावा बाईटकोड साथ famialiar नहीं कर रहे हैं
  • cglib (http://cglib.sourceforge.net/) कुछ उच्च स्तर कपोल-कल्पना
  • बाइट बडी (http://bytebuddy.net/) एक डीएसएल के माध्यम से कक्षाओं उत्पन्न करता है प्रदान एएसएम के शीर्ष पर बनाता है आरंभ करने के लिए है। सक्रिय रूप से बनाए रखा उपयोग और बढ़ते उपयोग

हालांकि मैं बाइटकोड मैनिपुलेशन में कूदने से पहले अन्य विकल्पों पर विचार करता हूं।

+0

बीएसएल को जेडीके –

+1

@ alexander.box में शामिल किया गया है: हाँ, एक्सएसएलटीसी ट्रांसफॉर्मर ज़लान की निर्भरता के रूप में, लेकिन यह गैर मानक API है और पैकेज com.sun.org.apache.bcel.internal में भी छिपा हुआ है ! बेहतर अपने जार प्रदान करें। – Daniel

+2

ओह, और जब मैं इसमें हूं: कक्षाओं का वाद्य यंत्र होने पर एएसएम बहुत अच्छा विकल्प है। समझने और उपयोग करने में आसान है। इसके अलावा यह एक बहुत अच्छा दस्तावेज है। – Daniel

6

कुछ वर्गों में तर्क जोड़ना उबाऊ हो सकता है, लेकिन जब तक आपके पास हैंडलर के हजारों न हों, वैसे ही मैं जाऊंगा। इसे सरल रखें

जिसके अनुसार,

Game.registerHandler(this); 

होगा अधिक वस्तु उन्मुख।

प्रत्येक कक्षा में तर्क जोड़ने का एक विकल्प फैक्ट्री पेश करना है जो हैंडलर को तुरंत चालू करने के लिए ज़िम्मेदार है।

HandlerFactory.createMouseHandler(); 

और विधि createMouseHandler शामिल की तरह

Handler mh = new MousheHandler(); 
registerHandler(mh); 
return mh; 

कुछ आप इन विकल्पों में से किसी में, मैं विचार करेगा नहीं करना चाहते हैं तो एक पहलू ढांचे (शायद AspectJ) या Invertion के लिए एक कंटेनर नियंत्रण (शायद वसंत आईओसी)। पहलू आपको चयनित स्रोतों पर अपने स्रोत, और "बुनाई" कोड को एनोटेट करने की अनुमति देते हैं। एक आईओसी कंटेनर आपको ऑब्जेक्ट के जीवन चक्र को नियंत्रित करने की अनुमति देता है (उदा। तत्काल)। दोनों दृश्य के पीछे बाइटकोड उपकरण का उपयोग करते हैं।

लेकिन यदि आप उपकरण स्वयं को करना चाहते हैं, तो मैं केवल जावास्स्ट और एएसएम की तुलना कर सकता हूं जिसे मैंने व्यक्तिगत रूप से उपयोग किया था।

एएसएम निम्न स्तर है, और वास्तव में जावा बाइटकोड के स्तर पर संचालित होता है। आपको इससे परिचित होना चाहिए। ढांचा बहुत अच्छी तरह से डिजाइन किया गया है, मैनुअल उत्कृष्ट है, और यह एक महान पुस्तकालय है। एक तरफ बाइटकोड के पैटर्न को प्रतिस्थापित करने के लिए जटिल हो सकता है, क्योंकि इसे एक तथाकथित "राज्यव्यापी" परिवर्तन की आवश्यकता होती है। एक तरफ, आपके पास बाइटकोड पर पूर्ण नियंत्रण है।

जावस्सिस्ट अधिक उच्च स्तर है। आप बाइटकोड के कच्चे स्तर पर काम नहीं करते हैं, थोड़ा उच्च स्तर, उदा। खेतों को पढ़ना/लिखना, संदेश भेजना, रचनाकार। साथ ही, यह आपको नियमित जावा सिंटैक्स का उपयोग करके परिवर्तन निर्दिष्ट करने की अनुमति देता है, जिसे फ्रेमवर्क द्वारा संकलित किया जाता है। एपीआई थोड़ा उलझन में है, क्योंकि परियोजना वर्षों से बढ़ी है। ढांचे के बारे में दस्तावेज है, लेकिन एएसएम के साथ इतना केंद्रीकृत नहीं है।

संबंधित मुद्दे