You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot微服务中用new初始化对象遇空指针异常及相关疑问

What Happens When Using new to Create Objects in SpringBoot?

Let's break down your questions clearly—they all tie back to how Spring manages its beans, which is key to avoiding headaches like NullPointerExceptions.

1. Behavior of new-Created Objects & Container Status

When you use the new keyword to instantiate an object in a SpringBoot app, that object exists entirely outside the Spring container. Here's what this means in practice:

  • Spring has no awareness of this object. It won’t track its lifecycle, trigger callbacks like @PostConstruct or @PreDestroy, or apply any dependency injection logic to it.
  • Annotations like @Autowired, @Resource, or @Value inside the object will be completely ignored. Spring won’t populate those fields with beans from its container.
  • AOP features (like @Transactional, @Cacheable) won’t work on this object. Spring creates proxies for beans it manages to enable these features—your manually instantiated object won’t get this proxy wrapping.

2. Why You’re Getting a NullPointerException (NPE)

The #1 cause of NPE with new-created objects is unresolved Spring-managed dependencies. Let’s use a common example:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepo;

    public User getUserById(Long id) {
        return userRepo.findById(id); // This will throw NPE if userRepo is null
    }
}

If you do UserService service = new UserService(); and call service.getUserById(1L), the userRepo field will be null. Since you created the object manually, Spring never had a chance to inject the UserRepository bean into it.

Other possible NPE triggers:

  • @Value-annotated configuration properties will stay null in a new-created object.
  • Trying to use other Spring-managed resources (like EntityManager, RestTemplate) that you didn’t manually initialize.

Fixes to Avoid NPE

Here are the most practical ways to resolve this issue:

  • Inject the bean instead of using new: If the class you need is a Spring-managed bean (marked with @Service, @Component, @Repository, etc.), just @Autowired it into the class where you need it:
    @RestController
    public class UserController {
        @Autowired
        private UserService userService; // Spring injects the managed bean here
    
        @GetMapping("/users/{id}")
        public User getUser(@PathVariable Long id) {
            return userService.getUserById(id); // No NPE here
        }
    }
    
  • Fetch the bean from the Spring context: If you absolutely need to create the object manually (e.g., in a non-Spring-managed class), you can retrieve the bean via ApplicationContext:
    @Component
    public class ContextProvider implements ApplicationContextAware {
        private static ApplicationContext context;
    
        @Override
        public void setApplicationContext(ApplicationContext ctx) throws BeansException {
            context = ctx;
        }
    
        public static <T> T getBean(Class<T> beanClass) {
            return context.getBean(beanClass);
        }
    }
    
    // Use it like this:
    UserService service = ContextProvider.getBean(UserService.class);
    
  • Use constructor injection: If you’re building a class that needs Spring dependencies, make it a Spring-managed bean and use constructor injection (this is Spring’s recommended approach for clarity and testability):
    @Service
    public class UserService {
        private final UserRepository userRepo;
    
        // Spring will automatically pass the UserRepository bean here
        public UserService(UserRepository userRepo) {
            this.userRepo = userRepo;
        }
    }
    

内容的提问来源于stack exchange,提问作者mohneesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:32:01