zoukankan      html  css  js  c++  java
  • Spring Bean的作用域以及lookup-method标签的使用

    Spring Framework支持五种作用域,如下图所示:

    singleton:表示一个容器中只会存在一个bean实例,无论在多少个其他bean里面依赖singleton bean,整个容器都只会存在一个实例。相当于是容器的全局变量。

    prototype:一个容器中可能会存在多个bean实例,prototype bean的实例产生有两种情况,一种是其他bean请求依赖prototype 容器会为其他bean分别创建一个实例。另外一种就是通过ApplicationContextAware 接口的 getBean方法获取 bean的时候 容器也会创建一个新的实例。

    request:这个不用多说,即容器会为每一个HTTP请求都会创建一个实例。

    session:容器会为每个session创建一个bean实例

    那么问题来了,由于bean的作用域不同,其实例创建的时间也不会相同,如果程序中存在一个 singleton bean 依赖了一个 request bean ,直接通过 @Autowired注解项目在启动的时候会报错的,如何解决这个问题呢?Spring 提供了lookup-method方法来解决这个问题。下面来看一个例子:

    1 首先新建一个User类

    public class User {

    private String name;

    private String password;

    private int age;
    //省略setter 和 getter
    }
    2 将这个User类注册成为 request 作用域的bean 在springContext.xml文件中
    <bean id="user" class="com.zsq.cn.login.entity.User" scope="request">
    <property name="name" value="zsq" />
    </bean>
    3 新建一个controller
    @Controller
    public class LoginController extends BaseException{
    @Autowired
    private LookupMethodService lookupMethodService;

    @RequestMapping("/")
    public String home(Model model){
    User user = lookupMethodService.getUser();
    System.out.println(user.toString());
    return "home/index";
    }
    }
    4 新建一个service 以及其实现类
    public interface LookupMethodService {

    User getUser();
    }

    @Service
    public abstract class LookupMethodServiceImpl implements LookupMethodService {

    @Override
    public User getUser() {
    return creatUser();
    }

    public abstract User creatUser();
    }
    5 在springContext.xml文件中配置

    <bean id="lookupMethodServiceImpl" class="com.zsq.cn.login.service.impl.LookupMethodServiceImpl">
    <lookup-method name="creatUser" bean="user" />
    </bean>


    通过5 的配置 4中的抽象方法 createUser将返回2中bean定义的一个新的实例。
    每次通过1 的请求时容器都会创建一个name=“”zsq“”的新实例。


    当然spring提供了一种更加简单的方式来处理作用域不一样时属性注入的问题。

    即使用@Scope标签的proxyMode属性。比如我要将一个Student注册为作用域为session的bean,并在单实例的loginController中注入。

    1 首先建立一个

    @Component
    @Scope(value="session",proxyMode=ScopedProxyMode.TARGET_CLASS)
    //如果Student是一个类,并没有实现任何接口,那么将proxyMode设置为ScopedProxyMode.TARGET_CLASS,将采用CGLIB代理,
    //如果Student实现了一个接口,那么可以将proxyMode设置为ScopedProxyMode.INTERFACES,将采用JDK的动态代理,
    public class Student {

    private String name;

    private int age;

    //省略setter、getter
    }
    如果要在xml文件中实现这一步可以在springContext.xml文件中注入

    <bean id="student" calss="com.zsq.cn.login.entity.Student" scope="session">
    <property name="name">zsq</property>
    <property name="age">22</property>
    //下面两个二选一
    <aop:scoped-proxy />//如果Student是一个类,并没有实现任何接口这样配置将采用CGLIB代
    <aop:scoped-proxy proxy-target-class="false" />//如果Student实现了一个接口,这样配置将采用JDK动态代理
    </bean>

    2 在loginController中注入student
    @Autowired
    private Student student;


    @RequestMapping("/")
    public String home(Model model){
    model.addAttribute("user", new User());

    student.setAge(22);

    return "home/index";
    }

    原文:https://blog.csdn.net/qq_34310242/article/details/78266035

  • 相关阅读:
    cf 785#
    hdu 4920 Matrix multiplication
    poj 2443 Set Operation
    bzoj 3687: 简单题
    洛谷 三月月赛 C
    洛谷 三月月赛 B
    洛谷 三月月赛 A
    bzoj 3156: 防御准备
    bzoj 3437: 小P的牧场
    bzoj 3675: [Apio2014]序列分割
  • 原文地址:https://www.cnblogs.com/PengChengLi/p/11076245.html
Copyright © 2011-2022 走看看