Self Invocation bypasses Proxy Saw a few posts about this recently, here's what I got in my reading. 🔹 Bean Management All beans in Spring are managed by DefaultListableBeanFactory, which extends DefaultSingletonBeanRegistry. The DefaultSingletonBeanRegistry is the one that actually stores the bean instances — a map of bean name → object reference. 🔹 What Happens with Proxies When we use annotations like @Transactional or @Async, Spring doesn’t just enhance the bean. It creates a proxy (often a CGLIB subclass) and registers that proxy in the registry instead of the original instance. So when another bean calls it, the call goes like: Caller → BeanFactory → Proxy → Actual Bean The proxy gets the call, applies the advice (transaction, async, etc.), and then runs the actual method. 🔹 Why Self Invocation Breaks It When a method calls another method inside the same bean: method1() { method2(); // self-invocation } …the JVM doesn’t go through the registry again. The .class file already contains the direct bytecode reference for method2(). So the call becomes: this.method2() → skips proxy → advice never triggered 🔹 How to Fix It Use AspectJ instead of proxy-based AOP. AspectJ does bytecode weaving, literally modifying the .class file so advice logic is embedded — no proxy needed. Whether you actually need AspectJ is a separate decision — most of the time, the default proxy setup is good enough. #Spring #Java #AOP #Transactional #Async
Ayush F.’s Post
More Relevant Posts
-
You every thought how Spring magically detects and manages your @Service, @Repository, or @Controller classes without you explicitly declaring them. Hmmmm..... Here is how 🧩 1. Annotation Discovery Spring uses annotation-based configuration to identify which classes should become Spring-managed beans. When you enable component scanning, Spring scans the specified package (and all its sub-packages) for stereotype annotations like: @Component – generic stereotype for any Spring-managed component @Service – marks a service-layer class @Repository – marks a DAO/persistence-layer class @Controller / @RestController – marks a web controller Once detected, these classes are automatically registered in the application context. ⚙️ 2. Bean Creation and Registration When Spring discovers these annotated classes, it creates bean instances and registers them in the ApplicationContext — Spring’s central container. This registry holds all managed beans and their dependencies. From here, Spring can easily perform dependency injection, lifecycle management, and configuration. Think of the ApplicationContext as a “bean directory” where every managed component lives — and where Spring looks whenever you use @Autowired. 🧠 3. Bean Configuration and Lifecycle After registering a bean, Spring applies configuration rules: Resolving and injecting dependencies Managing lifecycle callbacks (like @PostConstruct, @PreDestroy) Handling resource management and proxy creation (for AOP or transactions) Developers can fine-tune bean behavior using: Annotations (e.g., @Qualifier, @Scope) XML configuration (legacy style) Programmatic configuration (via @Bean methods) #java #spring #springboot #javadev #springcore #springboot #javaspring
To view or add a comment, sign in
-
-
𝘽𝙚𝙖𝙣 𝙎𝙘𝙤𝙥𝙚𝙨: @𝙎𝙞𝙣𝙜𝙡𝙚𝙩𝙤𝙣 𝙫𝙨. @𝙋𝙧𝙤𝙩𝙤𝙩𝙮𝙥𝙚—𝙒𝙝𝙮 𝙄𝙩 𝙈𝙖𝙩𝙩𝙚𝙧𝙨 𝙞𝙣 𝙈𝙞𝙘𝙧𝙤𝙨𝙚𝙧𝙫𝙞𝙘𝙚𝙨 𝗠𝗲𝘁𝗿𝗶𝗰: Incorrect bean scope usage is a leading cause of memory leaks in Spring microservices, often resulting in stale session data piling up and increased memory consumption. 𝗣𝗿𝗼𝗯𝗹𝗲𝗺: Many developers default to @Singleton for all services, causing unwanted shared state across requests and users, which leads to memory leaks and performance issues. 𝗧𝗵𝗲 𝗕𝘂𝗴: // ❌ WRONG: Stateful service as singleton (default) @Service public class UserSessionService { private Map<String, SessionData> sessionMap = new HashMap<>(); // Shared across all requests and users — leads to state leakage! } 𝗧𝗵𝗲 𝗙𝗶𝘅: // ✅ CORRECT: Use @Prototype for stateful beans @Service @Scope("prototype") public class UserSessionService { private Map<String, SessionData> sessionMap = new HashMap<>(); // New instance per request prevents cross-user leakage } 𝙊𝙧 𝙚𝙫𝙚𝙣 𝙗𝙚𝙩𝙩𝙚𝙧, 𝙧𝙚𝙛𝙖𝙘𝙩𝙤𝙧 𝙩𝙤𝙬𝙖𝙧𝙙𝙨 𝙨𝙩𝙖𝙩𝙚𝙡𝙚𝙨𝙨 𝙙𝙚𝙨𝙞𝙜𝙣 𝙬𝙝𝙚𝙣𝙚𝙫𝙚𝙧 𝙥𝙤𝙨𝙨𝙞𝙗𝙡𝙚 𝙛𝙤𝙧 𝙤𝙥𝙩𝙞𝙢𝙖𝙡 𝙨𝙘𝙖𝙡𝙖𝙗𝙞𝙡𝙞𝙩𝙮. 𝗥𝗲𝗮𝗹 𝗜𝗺𝗽𝗮𝗰𝘁: After one incident, I found 15,000 stale sessions accumulating in production memory due to accidental state retention in a singleton. Switching to prototype scope and stateless beans cut memory use by up to 70%. 𝗖𝗮𝗹𝗹-𝘁𝗼-𝗔𝗰𝘁𝗶𝗼𝗻: What’s your go-to bean scope strategy in your services? Have you ever tracked down a production memory leak caused by incorrect scope? #Java #SpringBoot #Microservices #MemoryLeak #BeanScope #SoftwareEngineering #BackendDevelopment #TechTips #Programming
To view or add a comment, sign in
-
This looks like a simple code, but most developers get it wrong Let’s look at this simple code final int[] arr = {1, 2, 3}; arr[0] = 99; 🧠 Many developers think final makes the entire array unchangeable — but that’s not true! ✅ What’s actually happening: The final keyword means the reference arr cannot be reassigned to point to a new array. But the contents of the array can still be modified. For example: arr[0] = 99; // ✅ Allowed arr = new int[]{4, 5, 6}; // ❌ Compilation error 📊 After modification: [99, 2, 3] 🧩 Key takeaway: > final makes the reference immutable, not the object itself. #Java #ProgrammingTips #InterviewQuestions #JavaDeveloper #LearningJava
To view or add a comment, sign in
-
Option 1: Concise & Achievement-Focused Solved a classic Linked List problem: "Remove Nth Node From End of List" (LeetCode #19)! Successfully implemented the Java solution. This exercise was a great review of using a dummy node and the two-pointer approach to handle linked list operations efficiently. Option 2: Detailed & Technical Insight Deep dive into Linked Lists today! Just wrapped up the LeetCode problem "19. Remove Nth Node From End of List." Key takeaway from the solution: The most robust approach involves: Using a dummy node to simplify edge cases (like removing the head). Employing the two-pointer technique (slow/fast or previous/current) to find the target node in a single pass. The challenge is positioning the 'previous' pointer correctly so that when the fast pointer hits the end, the previous pointer is exactly one node before the node to be removed. Great practice for improving pointer manipulation skills! Option 3: Simple & Direct Happy to share a successful solution for LeetCode 19: Remove Nth Node From End of List! https://lnkd.in/d5TRq5b9
To view or add a comment, sign in
-
-
🐛 Bugs & Beyond #5 — The Legacy Method from Hell 😈 ⚠️ The Problem: While modernizing our old Java project, I stumbled upon this beauty: findAllByStatusAndCreationTimestampLessThanEqualAndMerchantBuyerPlatformsIdOrderByCreationTimestampAscIdAsc Yes. That’s one single method name. Symptoms: 🧩 Developers too scared to touch it 📉 Zero readability 💥 Any new filter meant adding another 10 words 🧠 Nobody remembered what it actually did Root Cause: Legacy Spring Data JPA derived query hell — logic jammed into the method name itself. Every extra condition = one more And/Or/By… until your IDE scrolls horizontally like a train. 🚂 The Fix: Go Modern. Go Readable. Use the @Query annotation or Specification API to express logic clearly. Before: findAllByStatusAndCreationTimestampLessThanEqualAndMerchantBuyerPlatformsIdOrderByCreationTimestampAscIdAsc After: @Query(""" SELECT o FROM Order o WHERE o.status = :status AND o.creationTimestamp <= :timestamp AND https://lnkd.in/g5esQGeE = :platformId ORDER BY o.creationTimestamp, o.id """) List<Order> findEligibleOrders(...); Results: ✅ Readable, maintainable queries ✅ Easier to debug & extend ✅ New devs no longer crying in the stand-up Key Takeaways: 😵 Avoid ultra-long derived query names — they’re not badges of honor. 🧠 Prefer @Query or Specification for complex conditions. 🧹 Refactoring legacy JPA methods is spring cleaning for your sanity. #Java #SpringBoot #JPA #Hibernate #CodeSmell #LegacyCode #Refactoring #CleanCode #BackendDevelopment #SystemDesign #ORM #ReadableCode #SoftwareEngineering #BugsAndBeyond #DevLife #JavaTips #Programming #CodeQuality #SpringDataJPA
To view or add a comment, sign in
-
-
Problem 23 : LeetCode LeetCode Problem(268) Solved: First Missing Positive (Optimal In-Place Solution) 🤯 Problem: Given an unsorted array of integers, find the smallest positive integer that is not present in the array. This must be solved in O(n) time and O(1) extra space. My Approach: I solved this challenging problem using the Cyclic Sort algorithm for an optimal in-place solution. In-Place Hashing: I iterated through the array, ensuring that every number x (where 1≤x≤n) is placed at its correct index, which is x−1. For example, the number 3 belongs at index 2. Swapping: I repeatedly swapped elements that were out of place until they met the condition or were outside the valid range [1,n]. This effectively uses the array itself as a hash map. Final Scan: After the sorting phase, a final linear scan of the array quickly identified the first index i where arr[i] is not equal to i+1. The missing positive number is then i+1. Key Achievements: Time Complexity: Achieved an O(n) time complexity with a runtime of 1 ms, beating 31.66% of other Java submissions. Space Complexity: Achieved O(1) extra space, utilizing the array in-place. Memory: The solution used 47.56 MB of memory, beating 5.17% of other submissions. Link : https://lnkd.in/dJShvfwn
To view or add a comment, sign in
-
-
🚀 How a Single Annotation Made Our Java Backend 50x Faster Sometimes, performance issues hide in plain sight. In our case, it was a seemingly harmless @Transactional annotation. Here’s what happened 👇 We had: @Transactional @Query("SELECT u FROM User u WHERE u.id = :id") Optional<User> findById(@Param("id") Long id); This annotation was silently creating proxies, starting unnecessary transactions, and performing dirty checks — all for a simple read query. The fix? @Transactional(readOnly = true) public interface UserRepository extends JpaRepository<User, Long> {} 💡 Instant impact: 10ms → 0.2ms per query (50x faster!) 📊 Key takeaways: Use @Transactional(readOnly = true) for queries — avoids unnecessary flush checks Don’t annotate repository methods with @Transactional unless needed Always profile before guessing — tools like JProfiler, YourKit, or async-profiler reveal hidden bottlenecks Micro-optimizations scale — saving milliseconds per request can mean hours of CPU time saved daily Sometimes, small changes lead to massive performance wins. ⚡ #Java #SpringBoot #Performance #BackendDevelopment #CodeOptimization #TechLearning #SpringDataJPA
To view or add a comment, sign in
-
⚙️ What Really Happens When You Create an Object in Java (new Keyword Deep Dive) 🧠 We’ve all done this a thousand times 👇 User user = new User("Tushar", 27); …but have you ever wondered what really happens under the hood when you hit new? 🤔 Let’s peel it back step by step 👇 --- 🔹 1️⃣ Class Loading Before the JVM can create an object, it first checks if the class is loaded into memory. If not — the ClassLoader brings it in from disk, verifies it, and stores metadata in the method area. So User.class is now ready to roll 📦 --- 🔹 2️⃣ Memory Allocation The JVM allocates memory for that object inside the heap (not the stack!) 🏠 How much? Enough to hold all instance variables defined in the class. Each new call = new memory slot in the heap. --- 🔹 3️⃣ Default Initialization Before your constructor runs, default values (like 0, false, or null) are assigned to all instance variables. This ensures your object is in a safe, predictable state — no garbage data lying around. --- 🔹 4️⃣ Constructor Call Once memory is ready, the constructor executes. That’s where your custom logic runs — assigning parameters, initializing resources, etc. At this stage, your object is fully constructed 🧱 --- 🔹 5️⃣ Reference Assignment Finally, the variable (user in this case) on the stack gets a reference (pointer) to the object in the heap. That’s how the stack and heap work together 💡 --- ⚡ The Takeaway The new keyword isn’t just object creation — it’s class loading + memory allocation + initialization + reference linking all in one powerful step 🚀 So next time you type new, remember — you’re orchestrating one of the most elegant parts of the JVM’s design. --- 💬 Your turn: Did you know all these steps were happening behind that tiny new keyword? 👇 Or did this post make you see object creation differently? #Java #JVM #MemoryManagement #ObjectCreation #BackendDevelopment #SoftwareEngineering #CleanCode #JavaDeveloper
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development