Spring AOP กับ AspectJ


178

ฉันอยู่ภายใต้การแสดงผลที่ Spring AOP ใช้ดีที่สุดสำหรับงานเฉพาะแอปพลิเคชันเช่นความปลอดภัยการบันทึกธุรกรรม ฯลฯ เนื่องจากใช้หมายเหตุประกอบ Java5 ที่กำหนดเองเป็นเฟรมเวิร์ก อย่างไรก็ตาม AspectJ ดูเหมือนจะเป็นมิตรกับรูปแบบการออกแบบที่ฉลาดกว่า

ทุกคนสามารถเน้นข้อดีและข้อเสียต่าง ๆ ของการใช้ Spring AOP กับ AspectJ ในแอปพลิเคชัน Spring ได้หรือไม่?


3
เมื่อมีคำอธิบายประกอบอยู่ใน Spring แต่ยังมีอยู่ใน Java คุณควรใช้อะไร ชวา ตรรกะเดียวกันนี้ใช้กับฟังก์ชั่นนี้ ฤดูใบไม้ผลิคือฤดูใบไม้ผลิ ที่นี่วันนี้หายไปในวันพรุ่งนี้ (ผู้คน Remeber ใช้ Struts มาระยะหนึ่งก่อนถึงฤดูใบไม้ผลิ) AspectJ เป็นโซลูชันระยะยาวที่ต้องการ มันจะอยู่ได้นานกว่าฤดูใบไม้ผลิ ฉันไม่ได้ปฏิเสธสปริงเพียงแค่พูดถึงเรื่องนี้ ... : -;
inor

คำตอบ:


236

ข้อดีของ Spring-AOP

  • การใช้งานง่ายกว่า AspectJ เนื่องจากคุณไม่จำเป็นต้องใช้ LTW ( การทอผ้าแบบโหลดเวลา ) หรือคอมไพเลอร์ AspectJ

  • มันใช้รูปแบบพร็อกซีและรูปแบบมัณฑนากร

ข้อเสียของ Spring-AOP

  • นี่คือ AOP ตามพร็อกซีดังนั้นโดยพื้นฐานแล้วคุณสามารถใช้จุดเชื่อมต่อที่เรียกใช้งานวิธีการเท่านั้น
  • มุมมองจะไม่ถูกนำไปใช้เมื่อเรียกวิธีอื่นภายในคลาสเดียวกัน
  • อาจมีค่าใช้จ่ายรันไทม์เล็กน้อย
  • Spring-AOP ไม่สามารถเพิ่มมุมมองให้กับสิ่งใดก็ตามที่ไม่ได้สร้างโดยโรงงาน Spring

ข้อดีของ AspectJ

  • สิ่งนี้รองรับจุดเชื่อมต่อทั้งหมด หมายความว่าคุณสามารถทำอะไรได้
  • มีค่าใช้จ่ายรันไทม์น้อยกว่าของ Spring AOP

AspectJ จุดด้อย

  • ระวัง. ตรวจสอบว่าคุณได้รับการทอผ้าในสิ่งที่คุณต้องการจะสาน
  • คุณต้องการกระบวนการสร้างเสริมด้วย AspectJ Compiler หรือต้องตั้งค่า LTW (การทอผ้าแบบโหลดเวลา)

20
@Configurable ต้องใช้ AspecJ ผ่านทาง Spring จากเอกสาร:If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.
HDave

7
อีกนักโทษฤดูใบไม้ผลิ AOP สำหรับฉันเป็น stacktraces ยาวอ่านไม่ได้เพราะพร็อกซี่ตามวิธีการ
WRM

1
ส่วนที่ทำให้เกิดความสับสนในคำตอบ: การมีรันไทม์เหนือศีรษะเล็กน้อยสำหรับเครื่องมือหนึ่งและความเป็นไปได้ที่จะมีรันไทม์เหนือศีรษะเล็กน้อยสำหรับอีกเครื่องหนึ่งเป็นอย่างไร
Moreaki

16
@Moreaki: เขาพูดว่า 'ค่าใช้จ่ายเล็กน้อย' เป็นนักโทษและ 'ค่าใช้จ่ายเล็กน้อย' เป็นมืออาชีพ ความแตกต่าง 'a' มีความสำคัญมาก - ในภาษาอังกฤษ 'a' หมายถึง 'บางส่วน' ในขณะที่ 'น้อย' หมายถึง 'ไม่มีเลย'
wujek

1
เพียงแค่สงสัยอย่างรวดเร็วในข้อดี Spring AOP ของคุณ (จุดที่ 2) - หากเราใช้คำอธิบายประกอบ @Aspect ในฤดูใบไม้ผลิมันจะเป็น JJ AOP ในแง่มุมว่าในกรณีนี้จะใช้ Proxy (Run time) หรือการปรับเปลี่ยนไบต์ (คอมไพล์) เวลา). เพราะฉันอยู่ภายใต้ความประทับใจที่ AspectJ รวบรวมเวลาและ Spring AOP เป็นเวลารัน AOP กรุณาช่วย
Pedantic

21

นอกเหนือจากสิ่งที่คนอื่นได้กล่าวไว้ - เพียงเพื่อใช้ถ้อยคำใหม่there are two major differences:

  1. หนึ่งเกี่ยวข้องกับประเภทของการทอผ้า
  2. อีกประการหนึ่งของการนิยาม Joinpoint

Spring-AOP:รันไทม์ที่ทอผ่านพร็อกซีโดยใช้แนวคิดของdynamic proxy if interface exists or cglib library if direct implementation provided.

AspectJ:รวบรวมเวลาที่ใช้ในการทอผ้าAspectJ Java Tools(ajc compiler)หากมีแหล่งที่มาหรือการรวบรวมการโพสต์การทอผ้า (โดยใช้ไฟล์ที่รวบรวม) นอกจากนี้ยังสามารถเปิดใช้งานความเร็วในการโหลดการทอด้วยสปริง - มันต้องการaspectjไฟล์นิยามและให้ความยืดหยุ่น

การรวบรวมเวลาทอผ้าสามารถนำเสนอประโยชน์ของประสิทธิภาพ (ในบางกรณี) และยัง joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.


20

หมายเหตุเพิ่มเติม: หากประสิทธิภาพการทำงานภายใต้การโหลดสูงเป็นสิ่งสำคัญคุณจะต้องการ AspectJ ที่เร็วกว่าฤดูใบไม้ผลิ AOP 9-35xAOP 10ns กับ 355ns อาจจะไม่ฟังดูมากนัก แต่ฉันเคยเห็นผู้คนใช้ล็อตต่างๆ มูลค่า 10K ของแง่มุม ในกรณีเหล่านี้คำขอของคุณอาจมีหลายพันแง่มุม ในกรณีนี้คุณกำลังเพิ่ม ms ในคำขอนั้น

ดูมาตรฐาน


4
การวัดประสิทธิภาพที่web.archive.org/web/20150520175004/https://docs.codehaus.org/ …
เอียน

18

คู่มือผู้ใช้สปริงจะให้ข้อมูลจำนวนมากตรงจากปากม้า

บทที่ 6.4 - การเลือกรูปแบบการประกาศ AOP ที่จะใช้นั้นเป็นสิ่งที่ไม่ดีสำหรับคุณเนื่องจากจะกล่าวถึงข้อดีข้อเสียของทั้งคู่

วรรค6.1.2 - ความสามารถในการสปริง AOP และเป้าหมาย & บทที่6.2 - @ การสนับสนุน @Aspectและ6.8 - การใช้ AspectJ กับแอปพลิเคชันสปริงน่าสนใจเป็นพิเศษ


14

สปริง AOP เป็นหนึ่งในส่วนสำคัญของโครงสร้างสปริง ในขั้นตอนพื้นฐานมากกรอบสปริงจะขึ้นอยู่กับ IoC และ AOP ในเส้นทางที่เป็นทางการของฤดูใบไม้ผลิมีสไลด์ที่มันบอกว่า:

AOP เป็นหนึ่งในส่วนที่สำคัญที่สุดของกรอบ

จุดสำคัญสำหรับการทำความเข้าใจวิธีการทำงานของ AOP ในฤดูใบไม้ผลิคือเมื่อคุณเขียน Aspect with Spring เราได้กำหนดกรอบการทำงานด้วยการสร้าง proxy สำหรับวัตถุของคุณ JDKDynamicProxyถ้า bean ของคุณใช้อินเตอร์เฟสหรือผ่าน CGLIB ถ้า bean ของคุณไม่ได้ใช้ อินเตอร์เฟซ. จำไว้ว่าคุณต้องมี cglib 2.2 ใน class-path ของคุณหากคุณใช้ Spring ก่อนเวอร์ชัน 3.2 เริ่มต้นจาก Spring 3.2 มันไร้ประโยชน์เพราะ cglib 2.2 รวมอยู่ในแกน

เฟรมเวิร์กที่การสร้าง bean จะสร้างพร็อกซีที่ล้อมวัตถุของคุณและเพิ่มความรับผิดชอบข้ามความกังวลเช่นความปลอดภัยการจัดการธุรกรรมการบันทึกและอื่น ๆ

การสร้างพร็อกซีในลักษณะนี้จะถูกนำไปใช้เริ่มต้นสำหรับนิพจน์จุดตัดที่ใช้เป็นกรอบในการตัดสินใจว่าถั่วและวิธีการใดที่จะถูกสร้างเป็นพร็อกซี คำแนะนำจะเป็นความรับผิดชอบมากกว่ารหัสของคุณ โปรดจำไว้ว่าในกระบวนการนี้จุดตัดจะบันทึกเฉพาะวิธีสาธารณะที่ไม่ได้รับการประกาศเป็นขั้นสุดท้าย

ขณะนี้ใน Spring AOP การทอผ้าของ Aspects จะดำเนินการโดยคอนเทนเนอร์ที่การเริ่มต้นคอนเทนเนอร์ใน AspectJ คุณต้องดำเนินการนี้ด้วยการรวบรวมโพสต์โค้ดของคุณผ่านการปรับเปลี่ยนแบบ bytecode ด้วยเหตุผลนี้ฉันคิดว่าวิธีการแบบสปริงนั้นง่ายกว่าและจัดการได้ง่ายกว่า AspectJ

ในทางตรงกันข้ามกับ Spring AOP คุณไม่สามารถใช้พลังทั้งหมดของ AOP ได้เนื่องจากการใช้งานจะกระทำผ่านพร็อกซีและไม่ได้ผ่านการแก้ไขโค้ดของคุณ

เช่นเดียวกับใน AspectJ คุณสามารถใช้การทอผ้าแบบโหลดโหลดใน SpringAOP คุณสามารถได้รับประโยชน์จากฟีเจอร์นี้ในฤดูใบไม้ผลิซึ่งมีการใช้งานกับเอเจนต์และการกำหนดค่าพิเศษ@EnabledLoadWeavingหรือใน XML คุณสามารถใช้พื้นที่ชื่อเป็นตัวอย่าง อย่างไรก็ตามใน Spring AOP คุณไม่สามารถสกัดกั้นทุกกรณี ตัวอย่างเช่นnewคำสั่งไม่ได้รับการสนับสนุนใน Spring AOP

อย่างไรก็ตามใน Spring AOP คุณจะได้รับประโยชน์จากการใช้ AspectJ ผ่านการใช้aspectofวิธีการจากโรงงานในการกำหนดค่า spring bean

สำหรับเหตุผลที่ Spring AOP นั้นเป็นพร็อกซีที่สร้างจากคอนเทนเนอร์ดังนั้นคุณสามารถใช้ AOP สำหรับสปริงถั่วเท่านั้น ในขณะที่ใช้ AspectJ คุณสามารถใช้มุมมองในถั่วทั้งหมดของคุณ จุดเปรียบเทียบอีกประการหนึ่งคือการดีบักและความสามารถในการคาดการณ์พฤติกรรมของโค้ด ด้วย spring AOP งานจะถูก preform ทั้งหมดจากคอมไพเลอร์ Java และแง่มุมเป็นวิธีที่ยอดเยี่ยมสำหรับการสร้างพร็อกซีสำหรับ Spring bean ของคุณ ใน AspectJ หากคุณปรับเปลี่ยนรหัสคุณต้องรวบรวมและเข้าใจว่าลักษณะของผ้าทอของคุณเป็นอย่างไร แม้การปิดระบบการทอผ้าในฤดูใบไม้ผลิก็ง่ายขึ้นด้วยสปริงคุณสามารถลบมุมมองออกจากการกำหนดค่ารีสตาร์ทและใช้งานได้ ใน AspectJ คุณจะต้องคอมไพล์โค้ดอีกครั้ง!

ในการทอผ้าแบบโหลดความเร็ว AspectJ นั้นยืดหยุ่นกว่าสปริงเนื่องจากสปริงไม่รองรับตัวเลือกทั้งหมดของ AspectJ แต่ในความคิดของฉันหากคุณต้องการเปลี่ยนกระบวนการสร้างถั่ววิธีที่ดีกว่าคือการจัดการล็อกอินแบบกำหนดเองในโรงงานและไม่ใช่การทอผ้าแบบโหลดโหลดในแง่มุมที่เปลี่ยนพฤติกรรมของผู้ให้บริการใหม่ของคุณ

ฉันหวังว่าภาพมุมกว้างของ AspectJ และ Spring AOP นี้จะช่วยให้คุณเข้าใจถึงความแตกต่างของยาสองชนิด


0

เป็นสิ่งสำคัญที่จะต้องพิจารณาว่าแง่มุมของคุณจะเป็นภารกิจสำคัญหรือไม่และโค้ดของคุณถูกปรับใช้หรือไม่ สปริง AOP จะหมายถึงคุณต้องพึ่งพาการทอผ้าแบบโหลดครั้งเดียว สิ่งนี้อาจล้มเหลวในการสานและจากประสบการณ์ของฉันหมายความว่าข้อผิดพลาดในการบันทึกอาจมีอยู่ แต่จะไม่ป้องกันแอปพลิเคชันจากการทำงานโดยไม่ใช้โค้ดด้าน[ฉันจะเพิ่มข้อแม้ว่ามันอาจเป็นไปได้ กรณี; แต่ฉันไม่ได้ตระหนักถึงมันเป็นการส่วนตัว ] การทอแบบเวลาคอมไพล์หลีกเลี่ยงสิ่งนี้

นอกจากนี้หากคุณใช้ AspectJ ร่วมกับ Aspect-maven-plugin คุณจะสามารถเรียกใช้การทดสอบหน่วยกับลักษณะของคุณในสภาพแวดล้อม CI และมีความมั่นใจว่าสิ่งประดิษฐ์ที่สร้างขึ้นได้รับการทดสอบและทออย่างถูกต้อง ในขณะที่คุณสามารถเขียนการทดสอบหน่วยขับด้วยสปริงได้อย่างแน่นอนคุณยังไม่สามารถรับประกันได้ว่ารหัสที่ใช้งานจะเป็นสิ่งที่ผ่านการทดสอบถ้า LTW ล้มเหลว

สิ่งที่ต้องพิจารณาอีกประการหนึ่งคือคุณกำลังโฮสต์แอปพลิเคชันในสภาพแวดล้อมที่คุณสามารถตรวจสอบความสำเร็จหรือความล้มเหลวของการเริ่มต้นเซิร์ฟเวอร์ / แอปพลิเคชันโดยตรงหรือว่าแอปพลิเคชันของคุณถูกปรับใช้ในสภาพแวดล้อมที่ไม่อยู่ภายใต้การดูแลของคุณ จัดทำโดยลูกค้า] อีกครั้งนี้จะชี้วิธีการรวบรวมเวลาการทอผ้า

ห้าปีที่ผ่านมาฉันชื่นชอบสปริงมากขึ้นเพราะ AOP เป็นเหตุผลง่าย ๆ ที่ทำให้ทำงานได้ง่ายและมีโอกาสเคี้ยว IDE ของฉันน้อยลง อย่างไรก็ตามเนื่องจากความสามารถในการคำนวณและหน่วยความจำที่ใช้ได้เพิ่มขึ้นสิ่งนี้กลายเป็นปัญหาน้อยลงและ CTW เมื่อใช้กับ Aspj-maven-plugin กลายเป็นตัวเลือกที่ดีกว่าในสภาพแวดล้อมการทำงานของฉัน


0

นี้บทความยังมีคำอธิบายที่ดีเกี่ยวกับหัวข้อ

Spring AOP และ AspectJ มีเป้าหมายแตกต่างกัน

Spring AOP มีจุดประสงค์เพื่อให้การใช้งาน AOP ง่าย ๆ ทั่ว Spring IoC เพื่อแก้ไขปัญหาที่พบบ่อยที่สุดที่โปรแกรมเมอร์ต้องเผชิญ

ในทางกลับกัน AspectJ เป็นเทคโนโลยี AOP ดั้งเดิมที่มีจุดมุ่งหมายเพื่อให้โซลูชั่น AOP ที่สมบูรณ์


0

เปรียบเทียบกับ AOP, AspectJ ไม่จำเป็นต้องปรับปรุงคลาสเป้าหมายในเวลารวบรวม แต่จะสร้างคลาสพร็อกซีสำหรับคลาสเป้าหมายที่รันไทม์ซึ่งใช้อินเตอร์เฟสเดียวกันกับคลาสเป้าหมายหรือเป็นคลาสย่อยของคลาสเป้าหมาย

โดยสรุปอินสแตนซ์ของคลาสพร็อกซีสามารถใช้เป็นอินสแตนซ์ของคลาสเป้าหมายได้ โดยทั่วไปเฟรมเวิร์ก AOP ที่ได้รับการปรับปรุงเวลาคอมไพล์จะมีประโยชน์มากกว่าในด้านประสิทธิภาพการทำงานเนื่องจากเฟรมเวิร์ก AOP ที่ปรับปรุงแล้วที่รันไทม์ต้องการการปรับปรุงแบบไดนามิกทุกครั้งที่รัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.