proxyMode ScopedProxyMode.TARGET_CLASS 与 ScopedProxyMode.INTERFACE

spring

1个回答

写回答

Mstjam

2025-06-26 06:55

+ 关注

Spring
Spring

使用Spring框架进行开发时,我们经常会遇到需要在不同的作用域中管理bean的情况。为了解决这个问题,Spring提供了ScopProxyMode来定义bean的代理模式。其中,ScopedProxyMode.TARGET_CLASS和ScopedProxyMode.INTERFACE是两种常用的代理模式。

ScopedProxyMode.TARGET_CLASS的使用

在使用ScopedProxyMode.TARGET_CLASS模式时,Spring会为每个被代理的bean创建一个代理对象,该代理对象会被注入到其他需要引用该bean的地方。代理对象会继承原始bean的类型,因此可以在任何地方使用原始bean的方法和属性。

下面是一个使用ScopedProxyMode.TARGET_CLASS的简单示例:

Java

public interface UserService {

void addUser(String username);

}

@Service

@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)

public class UserServiceImpl implements UserService {

private String username;

@Override

public void addUser(String username) {

this.username = username;

}

}

@Component

public class UserController {

private final UserService userService;

public UserController(UserService userService) {

this.userService = userService;

}

public void createUser(String username) {

userService.addUser(username);

}

}

public class MAIn {

public static void mAIn(String[] args) {

ApplicationContext context = new AnnotationConfiGAPplicationContext(AppConfig.class);

UserController userController = context.getBean(UserController.class);

userController.createUser("John");

}

}

在上面的例子中,UserService使用了ScopedProxyMode.TARGET_CLASS代理模式。在UserController中,我们注入了UserService,并调用了其方法。由于UserService被代理,我们可以在UserController中直接使用UserService的方法。

ScopedProxyMode.INTERFACE的使用

与TARGET_CLASS不同,ScopedProxyMode.INTERFACE模式会为原始bean实现一个接口,并将代理对象注入到其他地方。这种模式下,代理对象只能通过接口进行访问,无法直接访问原始bean的方法和属性。

下面是一个使用ScopedProxyMode.INTERFACE的示例:

Java

public interface ShoppingCartService {

void addItem(String item);

List<String> getItems();

}

@Service

@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACE)

public class ShoppingCartServiceImpl implements ShoppingCartService {

private List<String> items = new ArrayList<>();

@Override

public void addItem(String item) {

items.add(item);

}

@Override

public List<String> getItems() {

return items;

}

}

@Controller

public class ShoppingCartController {

private final ShoppingCartService shoppingCartService;

public ShoppingCartController(ShoppingCartService shoppingCartService) {

this.shoppingCartService = shoppingCartService;

}

@PostMapping("/cart/add")

public String addItem(@RequestParam("item") String item) {

shoppingCartService.addItem(item);

return "redirect:/cart";

}

@GetMapping("/cart")

public ModelAndView viewCart() {

ModelAndView modelAndView = new ModelAndView("cart");

modelAndView.addObject("items", shoppingCartService.getItems());

return modelAndView;

}

}

public class MAIn {

public static void mAIn(String[] args) {

ApplicationContext context = new AnnotationConfiGAPplicationContext(AppConfig.class);

ShoppingCartController shoppingCartController = context.getBean(ShoppingCartController.class);

shoppingCartController.addItem("Apple");

shoppingCartController.addItem("Orange");

ModelAndView modelAndView = shoppingCartController.viewCart();

System.out.println(modelAndView.getModel().get("items"));

}

}

在上面的例子中,ShoppingCartService使用了ScopedProxyMode.INTERFACE代理模式。在ShoppingCartController中,我们注入了ShoppingCartService,并调用了其方法。由于ShoppingCartService被代理,我们只能通过接口来访问其方法,并且无法直接访问ShoppingCartServiceImpl的方法和属性。

小结

在Spring框架中,使用ScopedProxyMode.TARGET_CLASS和ScopedProxyMode.INTERFACE可以很方便地管理bean的作用域。TARGET_CLASS模式适用于需要在任何地方使用原始bean的方法和属性的情况,而INTERFACE模式适用于只需要通过接口访问bean的方法的情况。

无论是使用哪种代理模式,都需要根据实际需求来选择合适的作用域和代理模式。这样可以更好地管理bean的生命周期和作用域,提高应用的性能和可维护性。

举报有用(4)分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号