11.Bean使用拾遗(一)

本文深入探讨Spring框架中Bean的高级使用技巧,包括内部Bean的定义、null值处理、集合属性的合并策略、lookup方法注入、replace-method方法替换、request与session作用域的使用以及FactoryBean的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

11.Bean使用拾遗(一)

1. 内部bean

<bean id="a" class="com.xxx">
	<properties name="car">
    	<bean class="com.xxx.car" p:name="BMW">
        </bean>
    </properties>
</bean>

2. null值

<bean id="a" class="com.xx">
	<property name="name"><null/></property>
</bean>

3.集合合并,允许子继承父同名集合属性合集

<bean id="parentBoss" class="com.xxx">
	<property name="favorites">
    	<set>
        	<value>看报</value>
            <value>高尔夫</value>
        </set>
    </property>
</bean>

<bean id="chidBoss" class="com.xxx" parent="parentBoss">
	<property name="favorites">
        <set merge="true">
        	<value>爬山</value>
            <value>游泳</value>
        </set>
    </property>
</bean>

4.lookup方法注入

package com.desmond.springlearning.lookup;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:16
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private String name;
}

package com.desmond.springlearning.lookup;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:16
 */
public interface CarFactory {
    Car getCar();
}

package com.desmond.springlearning.lookup;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:22
 */
public class Test {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("lookup/application.xml");
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(resource);

        CarFactory carFactory = (CarFactory)xmlBeanFactory.getBean("carFactory");

        System.out.println(carFactory.getCar().getName());
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "
       default-autowire="default">

    <bean id="car" class="com.desmond.springlearning.lookup.Car" p:name="BMW" scope="prototype" />

    <bean id="carFactory" class="com.desmond.springlearning.lookup.CarFactory">
        <lookup-method name="getCar" bean="car"/>
    </bean>

</beans>

5.replace-method(方法替换)

package com.desmond.springlearning.method_replace;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:16
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private String name;
}

package com.desmond.springlearning.method_replace;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:33
 */
public class Boss1 {
    public Car getCar() {
        return new Car("BMW");
    }
}


package com.desmond.springlearning.method_replace;

import org.springframework.beans.factory.support.MethodReplacer;

import java.lang.reflect.Method;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:33
 */
public class Boss2 implements MethodReplacer{

    public Object reimplement(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println(o); // 目标对象,即boss1的代理对象
        System.out.println(method); // 目标方法,即boss1.getCar
        System.out.println(objects); // 目标方法的参数,即getCar的参数列表

        // 此行会抛出栈溢出错误
        // 原因:o 为 boss1 cglib的代理对象,代理了getCar方法,
        /*
            代理后的getCar 方法,方法体:
            boss2.reimplement(this, method, xxx);
            相当有自己调用自己,死循环.
         */
//        return method.invoke(o, objects);

        return new Car("LUHU.");
    }
}

package com.desmond.springlearning.method_replace;

import com.desmond.springlearning.lookup.CarFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/**
 * @author presleyli
 * @date 2018/10/24 下午9:22
 */
public class Test {
    public static void main(String[] args) {
        // 生成spring cglib 代理类文件
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/presleyli/java/desmond/codebase/spring-learning/src/main/java/com/desmond/springlearning/method_replace/clz");

        Resource resource = new ClassPathResource("method_replace/application.xml");
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(resource);

        Boss1 boss1 = (Boss1) xmlBeanFactory.getBean("boss1");
        Boss2 boss2 = (Boss2) xmlBeanFactory.getBean("boss2");

        System.out.println(boss1.getCar().getName());
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "
       default-autowire="default">

    <bean id="car" class="com.desmond.springlearning.method_replace.Car" p:name="BMW" scope="prototype" />

    <bean id="boss1" class="com.desmond.springlearning.method_replace.Boss1">
        <replaced-method name="getCar" replacer="boss2"/>
    </bean>

    <bean id="boss2" class="com.desmond.springlearning.method_replace.Boss2"/>

</beans>

6. rquest & session作用域

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
       default-autowire="default">

    <bean id="car" class="com.desmond.springlearning.method_replace.Car" p:name="BMW" scope="request" >
        <aop:scoped-proxy/>
    </bean>

    <bean id="boss1" class="com.desmond.springlearning.method_replace.Boss1">
        <property name="car" ref="car"/>
    </bean>

</beans>

此例中,boss1为单例,car,每次http请求都会创建一个新的代理类car.动态代理的逻辑如下:判断当前boss1属于哪个线程下 -> 取出该线程对应的httpSevletRequest -> 从request域中取出car(不存在则先创建) -> 使用;如果作用域为session, 过程如下:判断当前boss1属于哪个线程下 -> 拿到该线程对应的httpSevletRequest -> request.getSession() -> 从session里获取car(不存在则先创建) -> 使用.

  1. FactoryBean

    package com.desmond.springlearning.factory_bean;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author presleyli
     * @date 2018/10/24 下午9:16
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Car {
        private String name;
        private String slogon;
    }
    
    
    
    package com.desmond.springlearning.factory_bean;
    
    import org.springframework.beans.factory.FactoryBean;
    
    /**
     * @author presleyli
     * @date 2018/10/24 下午10:17
     */
    public class CarFactoryBean implements FactoryBean<Car>{
    
        private String carInfo;
    
        public Car getObject() throws Exception {
            String[] arr = this.getCarInfo().split(",");
    
            return new Car(arr[0], arr[1]);
        }
    
        public Class<?> getObjectType() {
            return Car.class;
        }
    
        public boolean isSingleton() {
            return true;
        }
    
        public String getCarInfo() {
            return carInfo;
        }
    
        public void setCarInfo(String carInfo) {
            this.carInfo = carInfo;
        }
    }
    
    
    
    package com.desmond.springlearning.factory_bean;
    
    import com.desmond.springlearning.lookup.CarFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;
    
    /**
     * @author presleyli
     * @date 2018/10/24 下午9:22
     */
    public class Test {
        public static void main(String[] args) {
            Resource resource = new ClassPathResource("factory_bean/application.xml");
            XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(resource);
    
            Car car = (Car)xmlBeanFactory.getBean("car");
            CarFactoryBean carFactory = (CarFactoryBean)xmlBeanFactory.getBean("&car");
    
            System.out.println(car);
            System.out.println(carFactory);
        }
    }
    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "
           default-autowire="default">
        <bean id="car" class="com.desmond.springlearning.factory_bean.CarFactoryBean" p:carInfo="BMW,被摸我!"/>
    
    </beans>
    
    output:
    十月 24, 2018 10:22:58 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [factory_bean/application.xml]
    
    Car(name=BMW, slogon=被摸我!)
    com.desmond.springlearning.factory_bean.CarFactoryBean@2133c8f8
    
    Process finished with exit code 0
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值