基于XML的Spring应用

基于XML的Spring应用

SpringBean配置详解

XML配置方式功能描述
idBean的id和全限定名配置,通过反射机制实现,如果不配id,就是bean的当前权限名class;如果没有配置id,而配置了name那么别名的第一个就是它的id
name为Bean设置别名,在没有设置的情况下,name就是id
scope包含singleton和prototype,主要区别在于创建实际的不同以及是否存放到单例池中,prototype在getbean时才会创建,并且不会存储到单例池中
lazy-init延迟加载,在使用ApplicationContext的情况下会在加载文件的时候直接创建,通过lazy-init我们可以让它进行延迟加载,首次getbean时候创建。只对ApplicationContext有效
init-method在完成Bean对象实例化之后执行。先执行构造方法,然后才是init方法
destroy-method只有在显式关闭的时候才会被调用。
autowire设置自动注入,可以按照类型也可以按照名字
factory-bean和factory-method指定使用哪个工厂Bean的哪个方法完成Bean的创建

别名的使用

<!-- 多个别名通过逗号隔开 如果没有配置id,而配置了name那么别名的第一个就是它的id -->
<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl">
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.itheima.service.dao.impl.UserDaoImpl"/>

Scope的测试使用

通过打断点的方式找到BeanFacory中的SingletonObject中的实例对象进行验证

public static void main(String[] args) {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserServiceimpl userService = (UserServiceimpl) applicationContext.getBean("userService");
    UserServiceimpl userService2 = (UserServiceimpl) applicationContext.getBean("userService");
    UserServiceimpl userService3 = (UserServiceimpl) applicationContext.getBean("userService");

    // userService.show();
    System.out.println(userService);
    System.out.println(userService2);
    System.out.println(userService3);
}
<!-- 多个别名通过逗号隔开 如果没有配置id,而配置了name那么别名的第一个就是它的id -->
<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl" scope="singleton">
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.itheima.service.dao.impl.UserDaoImpl"/>

Lazy-init的测试使用代码和上面基本一致

在测试过程中注意使用打断点方式进行验证

Destroy-Method和init-Method

public static void main(String[] args) {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserServiceimpl userService = (UserServiceimpl) applicationContext.getBean("userService");

    // userService.show();
    System.out.println(userService);

    applicationContext.close();
}
<!-- 多个别名通过逗号隔开 如果没有配置id,而配置了name那么别名的第一个就是它的id -->
<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl" init-method="init" destroy-method="destroy">
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.itheima.service.dao.impl.UserDaoImpl"/>

InitializingBean方法

在属性设置之后会执行这个方法,也就是哪些setxxx方法执行之后,在init-method之前

public class UserServiceimpl implements UserService, InitializingBean {

    private UserDao userDao;

    public UserServiceimpl(){
        System.out.println("UserServiceimple Create");
    }
    
    public void init(){
        System.out.println("init_method...");
    }

    // 该方法由BeanFactory进行调用,从容器中获取UserDao设置到此位置
    public void setUserDao(UserDao userDao){
        // System.out.println("UserDao input UserService: " + userDao);
        this.userDao = userDao;
    }

    public void destroy(){
        System.out.println("destroy_method...");
    }

    // 在属性设置之后执行,也就是在在所有set执行完之后
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet executing");
    }

}

实例化有参构造方法

<!-- 多个别名通过逗号隔开 如果没有配置id,而配置了name那么别名的第一个就是它的id -->
<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl" init-method="init" destroy-method="destroy">
    <constructor-arg name="args" value="123123123"/>
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
</bean>

静态工厂方法

public class MyBeanFactory1 {
    public static UserDao userDao(){
        return new UserDaoImpl();
    }
}
<!-- 静态工厂方法 -->
<!-- 通过静态工厂方法,能够将com.itheima.service.factory.MyBeanFactory1中的userDao方法的返回值作为创建的bean对象 -->
 <bean id="userDao1" class="com.itheima.service.factory.MyBeanFactory1" factory-method="userDao"/>

实例工厂对象方法

静态工厂和动态的区别在于静态工厂直接指定class的方法创建一个Bean对象,实例工厂则是通过已有的某个Bean的其中一个方法创建一个Bean。

<!-- 实例工厂方法 -->
 <bean id="userDao2" class="com.itheima.service.factory.MyBeanFactory2"/>
 <bean id="myBeanFactory2" factory-bean="beanFactory2" factory-method="userDao"/>
有参形式
<bean id="userDao1" class="com.itheima.service.factory.MyBeanFactory1" factory-method="userDao">
    <constructor-arg name="name" value="name"/>
    <constructor-arg name="age" value="11"/>
</bean>

实现FactoryBean规范延迟Bean实例化

public class MyBeanFactory3 implements FactoryBean<UserDao> {

    // 在程序getBean的时候获取的并不是MyBeanFactory3,而是getObject方法的返回对象,在main中打断点测试可以发现这个UserDao是被加载到factoryBeanObjectCache中,并且是在getbean时候被放入的,存在延迟加载
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}

参数注入

不管是property还是constructor-arg,如果是普通的参数值都是用value,如果是bean的引用就是用ref

<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl" init-method="init" destroy-method="destroy">
    <constructor-arg name="args" value="123123123"/>
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
</bean>

如果是集合,List Map等

<bean id="userService" name="aaa,bbb" class="com.itheima.service.impl.UserServiceimpl" init-method="init" destroy-method="destroy">
    <constructor-arg name="args" value="123123123"/>
    <!-- 将userDao传入到setUserDao方法中 注意这边使用的是ref标签 -->
    <property name="userDao" ref="userDao"/>
    <!-- 传入List集合参数 -->
    <property name="stringList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
        </list>
    </property>
    <property name="userDaoList">
        <list>
            <bean class="com.itheima.service.dao.impl.UserDaoImpl"></bean>
            <ref bean="userDao"></ref>
        </list>
    </property>
</bean>
<!-- set数据类型 -->
<property name="strSet">
    <set>
        <value>xxx</value>
        <value>yyy</value>
    </set>
</property>
<property name="userDaoSet">
    <set>
        <ref bean="userDao"></ref>
    </set>
</property>
<!-- Map以及Properties -->
<property name="userDaoMap">
    <map>
        <entry key="d1" value-ref="userDao"></entry>
    </map>
</property>
<property name="properties">
    <props>
        <prop key="p1">ppp1</prop>
    </props>
</property>

Bean的自动装配

自动装配是指对创建Bean对象的时候,如果其类的内部存在Set方法设置一些参数,那么autowire将会根据名字或者类型进行自动参数输入。

  • Byname:根据beanName进行装配
  • ByType:根据类型进行装配
<!-- autowire userService中的一些set方法将根据其name进行自动的装填配置 -->
<bean id="userService" class="com.itheima.service.impl.UserServiceimpl" autowire="byType"/>

<bean id="userDao" class="com.itheima.service.dao.impl.UserDaoImpl"/>

命名空间的种类

第一个xmln表示默认命名空间,第二行的那个在时候的时候是要加上xsi:…;如果需要加上自己需要的标签就可以相应添加,例如这里的context

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">

标签的使用

beans标签可通过prifile来区分测试环境与运行环境 ,如果没有被包含在任何环境下的默认标签,则表示公共使用,另外beans在使用的时候需要放在默认标签的后面,否则会报错,存在顺序问题。

<beans profile="dev">
    <bean id="xxxx" class="com.itheima.service.impl.UserServiceimpl"></bean>
</beans>
<beans profile="test">
    <bean id="xxxx" class="com.itheima.service.impl.UserServiceimpl"></bean>
</beans>
    public static void main(String[] args) {

        // 指定需要的springXML环境
        System.setProperty("spring.profiles.active","dev");

        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("xxxx");
        userService.show();
        
        applicationContext.close();
    }

导入配置其他的xml文件

<import resource="classpath:beans.xml"></import>

标签为bean取别名

<!-- name参数是bean的name,alias是新设置的别名 其实和bean中的name作用一样-->
<alias name="userDao" alias="dao"/>

引入第三方命名空间

  1. 首先需要找到对应的jar包
  2. 然后通过网络资料在命名空间中夹着对应的配置
  3. 最后可以直接使用

三种不同的getbean方式

// 通过beanname进行获取
UserService userService = (UserService) applicationContext.getBean("userService");
// 通过Bean的参数类型以及name进行获取
UserService userService1 = applicationContext.getBean("userService", UserService.class);
// 通过bean类型进行获取,这种方法要求类型唯一 这里也可以写UserServiceimple.class
UserService userService2 = applicationContext.getBean(UserService.class);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值