Spring中Bean对象创建方式的梳理

Spring中Bean对象创建方式的梳理

____刚开始接触Spring框架的时候,觉得他的IOC反转控制巧妙得很,不由得兴趣盎然动力满满。进一步学习过后才发现里面Bean对象的创建让人眼花缭乱,容易让人蒙圈(对初学者而言,大佬请加速通过)。从一开始在代码里直接用工厂模式创建,到用XML配置,用注解,用配置类配置等,今天在这里理清一下Bean对象创建的集中方式.

第一种:创建工厂生产Bean对象

____首先最原始的方法是通过自己建立工厂类,读取properties配置文件里的类,通过反射创建出类对象并将其放入自建的Map容器中,在需要用到bean的地方通过工厂的getBean方法直接获取。代码如下:

//这是properties配置文件里的内容
accountService=com.ilcosmo.service.impl.AccountServiceImpl
accountDao=com.ilcosmo.dao.impl.AccountDaoImpl
//这是工厂类的内容
private static Properties props;
private static Map<String,Object> beans;
static {
    try {
        props = new Properties();
        InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        props.load(in);
        beans = new HashMap<String,Object>();
        Enumeration keys = props.keys();
        while (keys.hasMoreElements()){
            String key = keys.nextElement().toString();
            String beanPath = props.getProperty(key);
            Object value = Class.forName(beanPath).newInstance();
            beans.put(key,value);
        }
    }catch (Exception e) {
        throw new ExceptionInInitializerError("初始化properties失败");
    }
}
//需要bean对象时,直接这样调用,即可获取对应的bean对象
private IAccountDao accountDao = (IAccountDao)BeanFactory.getBean("accountDao");

第二种:通过XML文件配置

____这种配置包含基础配置和注入配置。配置后在类里通过spring的容器获得bean对象,或者通过set方法获取。

基础配置:即只靠默认构造方法生成bean对象,无构造参数

____直接选择基础的xml,配置bean标签中的id属性和class属性即可,其他scope等属性后面单独讲实例时再说。如:

//id即为获取bean对象时用的标识,class为bean对象对应的全限定类名
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    把对象的创建交给spring管理-->
    <bean id="accountService" class="com.ilcosmo.service.impl.AccountServiceImpl"></bean>
    <bean id="accountDao" class="com.ilcosmo.dao.impl.AccountDaoImpl"></bean>
</beans>

注入配置:在生成bean对象时同时加入对象的属性

这里又有两种方式注入数据,一是通过set方法注入(常用)

____这里能注入的属性包括基本数据类型和String类型、其他bean对象、复杂类型。基本数据类型和String类型、其他bean对象直接用bean标签里的子标签,需要配置property的属性为name和value或者ref(注入其他bean对象时使用)。复杂类型如集合等这里先不说。如:

//使用Spring jdbc时的bean.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="jdbcTeamplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="ds"></property>
    </bean>
    <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value=""></property>
    </bean>
</beans>
二是通过构造方法注入

____这种方法有很大的弊端,在不需要对象所有属性都有值时也必须得输入对应的值(构造方法的要求,没有要求的入参,无法调用构造方法)。如:

//省略其他重复内容
<bean id="accountService" class="com.ilcosmo.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value="test"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

第三种:通过注解配置

____注解配置也需要配置xml,xml文件的头于前面单纯靠xml配置的头部内容有差别。这里xml主要配置spring创建容器时需要扫描的包,在包里对应的类上添加@Component后,spring框架即可在读取完配置文件之后在容器里创建该类对应的bean对象。除此外,spring还按功能给我们提供了三个更细化的注解:@service @Controller @repository,分别表示业务层的bean,表现层的bean,持久层的bean。
____配置后在类中同样通过spring容器获取bean对象。
____注解配置里还有参数注入的相关注解,后面再慢慢搞搞。

//bean.xml文件的内容
<?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: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">

    <!-- 告知spring在创建容器时要扫描的包 -->
    <context:component-scan base-package="com.ilcosmo"></context:component-scan>
</beans>    
//代码里业务层bean的注解
@Service("accountService")
//@Scope("prototype")
public class AccountServiceImpl implements IAccountService {}

第四种:通过配置类配置

____这种方式实际也是通过注解配置,只是将xml里的注解转移到了一个类里面。新建一个类,通过注解@Configuration将其标注为注解类,并用@ComponentScan(“com.ilcosmo”)指定spring创建容器时需要扫描的包,相当于xml中的<context:component-scan base-package=“com.ilcosmo”</context:component-scan>配置,在获取spring容器时,也转用new AnnotationConfigApplicationContext(SprinConfigration.class)来获取容器,其中的入参即是之前配置的配置类。如:

//配置类
@Configuration
@ComponentScan("com.ilcosmo")
public class SprinConfigration {
    @Bean//作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
        //name:用于指定bean的id,当不写时默认时方法名
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }
    @Bean(name = "dataSource")
    public DataSource createDataSource(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
            ds.setUser("root");
            ds.setPassword("");
            return ds;
        } catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

总结

____第一中用工厂创建获取bean对象的方式开发中一般不用,第二种xml配置一般适合生成引入jar包中bean对象时使用,第三种注解的方法一般适合生成自己类bean对象时使用,第四种和第三种一样。
____有错误或不当希望轻喷,小白身子弱胆子小扛不住。理解有误的地方欢迎指指点点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值