基于mvc模式的应用框架之spring(二)

本文详细介绍了Spring框架中IOC容器的应用,包括对象创建、依赖注入、单例与多例模式等核心概念,并提供了实例代码说明。

一.spring框架的简单应用

通过工厂类得到IOC容器创建的对象
直接得到IOC容器对象

public class App
{
    @Test
    public void testIOC() throws Exception 
    {
        // 创建对象
        // User user = new User();
        // 现在,把对象的创建交给spring的IOC容器
        Resource resource = new ClassPathResource("xml文件名称");
        // 创建容器对象(Bean的工厂), IOC容器 = 工厂类 + applicationContext.xml
        BeanFactory factory = new XmlBeanFactory(resource);
        // 得到容器创建的对象
        User user = (User) factory.getBean("user");
        System.out.println(user.getId());
    }

    @Test
    public void testAc() throws Exception
     {
        // 得到IOC容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("xml文件名称");
        // 从容器中获取bean
        User user = (User) ac.getBean("user");

        System.out.println(user);
    }
}

二.bean对象创建的细节

1) 对象创建: 单例/多例

scope=”singleton”, 默认值, 即 默认是单例【service/dao/工具类】
scope=”prototype”, 多例;【Action对象】

2) 什么时候创建?
scope=”prototype” 在用到对象的时候,才创建对象。
scope=”singleton” 在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。

3)是否延迟创建
lazy-init=”false” 默认为false, 不延迟创建,即在启动时候就创建对象
lazy-init=”true” 延迟初始化, 在用到对象的时候才创建对象(只对单例有效)

4) 创建对象之后,初始化/销毁
init-method=”init_user” 【对应对象的init_user方法,在对象创建之后执行 】
destroy-method=”destroy_user” 【在调用容器对象的destriy方法时候执行,(容器用实现类)】

public void testIOC() throws Exception
{
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("xml文件名称");
    System.out.println("-----容器创建-----");
    User user1 = (User) ac.getBean("user");
    User user2 = (User) ac.getBean("user");
    System.out.println(user1);
    System.out.println(user2);
    ac.destroy();
}

三.SpringIOC容器

1 创建对象
javaBean代码
public class User 
{
    private int id;
    private String name;
    public User()
    {
        super();
        System.out.println("User对象创建【无参数构造器】");
    }

    public User(int id, String name) 
    {
        System.out.println("User对象创建【带参数构造器】");
        this.id = id;
        this.name = name;
    }

    public int getId()
    {
        return id;
    } 

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()  
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    @Override
    public String toString()  
    {
        return "User [id=" + id + ", name=" + name + "]";
    }

    public void init_user()  
    {
        System.out.println("创建对象之后,初始化");
    }
    public void destroy_user()  
    {
        System.out.println("IOC容器销毁,user对象回收!");
    }
}
工厂
public class ObjectFactory
 {
    // 实例方法创建对象
    public User getInstance() 
    {
        return new User(100,"工厂:调用实例方法");
    }
    // 静态方法创建对象
    public static User getStaticInstance()  
    {
        return new User(101,"工厂:调用静态方法");
    }
}
测试代码
public class App
{
    @Test
    public void testIOC() throws Exception
    {
        ApplicationContext ac = new ClassPathXmlApplicationContext("xml文件名称");
        User user = (User) ac.getBean("user");
        System.out.println(user);
    }

    @Test
    public void testObj() throws Exception 
    {
        ApplicationContext ac = new ClassPathXmlApplicationContext("xml文件名称");
        User user = (User) ac.getBean("1test");
        System.out.println(user);
    }
}

1). 默认无参数构造器

<bean id="user1" class="包名.User"></bean>

2). 带参数构造器

<bean id="user2" class="包名.User">
    <constructor-arg index="0" type="int" value="100"></constructor-arg>
    <constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>

3). 定义一个字符串,值是”Jack” ; String s = new String(“jack”)

<bean id="str" class="java.lang.String">
    <constructor-arg value="Jacks"></constructor-arg>
</bean>

<bean id="user3" class="包名.User">
    <constructor-arg index="0" type="int" value="100"></constructor-arg>
    <constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg>
</bean>

3). 工厂类创建对象
3.1). 工厂类,实例方法
先创建工厂

3.2). 工厂类: 静态方法
class 指定的就是工厂类型
factory-method 一定是工厂里面的“静态方法”

<bean id="user" class="包名.ObjectFactory" factory-method="getStaticInstance"></bean>

4). 对象写法
问题:spring配置文件中,bean节点的id与name属性的区别?
id 不能有特殊符号, 且唯一,且不能以数字开始
name 可以有特殊符号

<bean id="test" name="1test"  class="包名.User"></bean>
2.对象依赖关系

Spring中,给对象赋值的方式有一下几种 【DI, 依赖注入】

1) 通过构造函数
2) 通过set方法给属性注入值
3) p名称空间
4)自动装配(了解)
5) 注解
javaBean代码
public class User 
{
    private int id;
    private String name;

    public void setId(int id)  
    {
        this.id = id;
    }

    public void setName(String name) 
    {
        this.name = name;
    }

    public int getId()  
    {
        return id;
    }

    public String getName()  
    {
        return name;
    }

    @Override
    public String toString()  
    {
        return "User [id=" + id + ", name=" + name + "]";
    }

    public User()  
    {
        super();
        System.out.println("User对象创建【无参数构造器】");
    }

    public User(int id, String name) 
    {
        System.out.println("User对象创建【带参数构造器】");
        this.id = id;
        this.name = name;
    }

    public void init_user()  
    {
        System.out.println("创建对象之后,初始化");
    }

    public void destroy_user()  
    {
        System.out.println("IOC容器销毁,user对象回收!");
    }
}
模拟Action部分代码
public class UserAction
 {
    private UserService userService;
    public void setUserService(UserService userService) 
    {
        this.userService = userService;
    }

    public String execute()  
    {
        userService.save();
        return null;
    }
} 
模拟Service部分代码
public class UserService
 {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) 
    {
        this.userDao = userDao;
    }

    public void save() 
    {
        userDao.save();
    }
}
模拟Dao部分代码
public class UserDao  
{
    public void save()
    {
        System.out.println("DB:保存用户");
    }
}

1). 通过构造函数

<bean id="user1" class="包名.User" scope="prototype">
    <constructor-arg value="100"></constructor-arg>
    <constructor-arg value="Tom"></constructor-arg>
</bean>

2). 通过set方法给属性注入值

<bean id="user" class="包名.User" scope="prototype">
    <property name="id" value="101"></property>
    <property name="name" value="Jack"></property>
</bean>

案例:action/service/dao

<bean id="userDao" class="包名.UserDao"></bean>

<bean id="userService" class="包名.UserService">
    <property name="userDao" ref="userDao"></property>
</bean>

<bean id="userAction1" class="包名.UserAction">
    <property name="userService" ref="userService"></property>
</bean>

3).内部bean

<bean id="userAction" class="包名.UserAction">
    <property name="userService">
        <bean class="包名.UserService">
            <property name="userDao">
                <bean class="包名.UserDao"></bean>
            </property>
        </bean>
    </property>
</bean>

4). 给对象属性注入值: p 名称空间给对象的属性注入值 (spring3.0以上版本才支持)

<bean id="userDao" class="包名.UserDao"></bean>

<bean id="userService" class="包名.UserService" p:userDao-ref="userDao"></bean>

<bean id="userAction" class=包名.UserAction" p:userService-ref="userService"></bean>

传统的注入

 <bean id="user" class="包名.User" >
    <property name="name" value="xxx"></property>
 </bean>

p名称空间优化后

<bean id="user" class="包名.User" p:name="Jack0001"></bean>

5).自动装配

javabean代码
public class User 
{
    private int id;
    private String name;

    public void setId(int id)  
    {
        this.id = id;
    }

    public void setName(String name) 
    {
        this.name = name;
    }

    public int getId()  
    {
        return id;
    }

    public String getName()  
    {
        return name;
    }

    @Override
    public String toString()  
    {
        return "User [id=" + id + ", name=" + name + "]";
    }

    public User()  
    {
        super();
        System.out.println("User对象创建【无参数构造器】");
    }

    public User(int id, String name) 
    {
        System.out.println("User对象创建【带参数构造器】");
        this.id = id;
        this.name = name;
    }

    public void init_user()  
    {
        System.out.println("创建对象之后,初始化");
    }

    public void destroy_user()  
    {
        System.out.println("IOC容器销毁,user对象回收!");
    }
}
模拟Action部分代码
@Component("userAction")  
public class UserAction 
{
    @Resource(name = "userService")
    private UserService userService;

    public void setUserService(UserService userService) 
    {
        this.userService = userService;
    }
}
模拟Service部分代码
@Component("userService")  // userService加入ioc容器
public class UserService
{
    // 会从IOC容器中找userDao对象,注入到当前字段
    /*
     * <bean id="" class=""> 
     *    <property name="userDao" ref="userDao" />    @Resource相当于这里的配置
     * </bean>
     */

    @Resource(name = "userDao")
    private UserDao userDao;

    public void setUserDao(UserDao userDao) 
    {
        this.userDao = userDao;
    }

    public void save() 
    {
        userDao.save();
    }
}
模拟Dao部分代码
// 把当前对象加入ioc容器
@Component("userDao")   //  相当于bean.xml 【<bean id=userDao class=".." />】
public class UserDao  
{
    public void save()  
    {
        System.out.println("DB:保存用户!!!");
    }
}

1).自动装配

<bean id="userDao" class="包名.UserDao"></bean>   
<bean id="userService" class="包名.UserService"></bean>

2). 如果根据类型自动装配: 必须确保IOC容器中只有一个该类型的对象

<bean id="userAction" class="包名.UserAction"></bean>

<bean id="userService_test" class="包名.UserService" autowire="byType"></bean>
注解

注解方式可以简化spring的IOC容器的配置!
使用注解步骤:
1)先引入context名称空间
xmlns:context=”http://www.springframework.org/schema/context”
2)开启注解扫描

3)使用注解
通过注解的方式,把对象加入ioc容器。
创建对象以及处理对象依赖关系,相关的注解:
@Component 指定把一个对象加入IOC容器

@Repository 作用同@Component; 在持久层使用
@Service 作用同@Component; 在业务逻辑层使用
@Controller 作用同@Component; 在控制层使用
@Resource 属性注入

1). 使用注解,可以简化配置,且可以把对象加入IOC容器,及处理依赖关系(DI)
2). 注解可以和XML配置一起使用。
3).开启注解扫描

<context:component-scan base-package="包名"></context:component-scan>

<context:component-scan base-package="包名"></context:component-scan>

<bean id="userDao" class="包名.UserDao" scope="prototype">
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The_Web3_社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值