带有生命周期的bean
生命周期:创建和销毁
ioc容器注册的bean对象:
单实例
容器启动的时候会创建好,容器关闭的时候也会销毁创建好的bean对象
就是在bean的标签里面有一个“scope”属性,当然默认是单实例的(singleton)
<bean id="book2" class="com.yxm.entity.Book" init-method="myInit" destroy-method="myDestory" scope="singleton"></bean>
多实例
获取(getBean()方法)的时候才会创建,但是容器关闭的时候不会自动帮你销毁
和单实例的类似就是属性scope的值变化了
<bean id="book3" class="com.yxm.entity.Book" init-method="myInit" destroy-method="myDestory" scope="prototype"></bean>
还有就是其中的init-method和destroy-method方法,也就是初始化之前产生的和销毁后会调用的方法
bean的后置处理器
概念
Spring有一个接口,后置处理器:可以在bean的初始化前后调用方法,而且他不是针对的是一个bean对象,而是所有的bean对象
创建
需要创建一个类来实现接口BeanPostProcessor并且重写两个方法postProcessBeforeInitialization和postProcessAfterInitialization,也就是初始化前调用和初始化之后调用,因为创建了类了,然后又想要spring去自动调用,在bean对象初始化的时候,所以需要进行注册这个bean对象。
到了最后就是bean对象的初始化前,init-method所对应的方法,然后是初始化后的方法,最后就是销毁时所要调用的方法。
需要注意的一点是,在后置处理器里面的两个方法的返回值返回的一般都是方法里面的第一个参数的值(因为返回的是什么值,那么容器内部最后就是什么值)
引用外部属性文件
数据库连接池(作为单实例最好,一个项目只有一个连接池,连接从连接池里面调用),所以可以吧连接池交给spring进行管理
<!-- 引用外部属性文件 -->
<!-- 因为在spring5之前的都是有username的关键字的,所以再使用spring框架的时候应该避免,spring5以后就当我没说 -->
<context:property-placeholder location="classpath:jdbcConfig.properties"/>
然后就是和之前的数据库连接池连接类似了,就是把value里面用${}表达式引用对应的属性名,比如这样
<property name="user" value="${jdbc.username}"></property>
//进行调用
/按照类型获取组件会获取到这个类型下的所有实现的子类等等
DataSource dataSource = ac.getBean(DataSource.class);
//ComboPooledDataSource dataSource = ac.getBean("dataSource",ComboPooledDataSource.class);
//就会获取相同的一个bean对象,当然前提是你这个DataSource是只有一个bean对象的,不然按照类型进行获取的话,范围更大
ecplise里面有新建源文件夹和文件夹,前者是会把源文件夹里面的文件加载到bin目录下,而文件夹下的就没有,该在哪一级,就在哪一级。
基于xml的自动配置
会为类的属性进行自动赋值
<!-- 前提是所创建的bean的对象里面的属性是自定义的属性,如果是基本类型的话,就别想了 -->
<bean id="car6" class="com.yxm.entity.Car">
<property name="carName" value="luhu"></property>
<property name="color" value="红色"></property>
</bean>
<!-- 测试自动配置 -->
<!--
autowire="default":是由这个属性决定的,默认情况下是不会进行自动配置的(default)
autowire="byName" :可以理解为ac.getBean("car");这里面的car是和person11的类对象的属性变量名是一致的,如果没有找到的话就赋值null
autowire="byType" : 可以理解为ac.getBean(Car.class);也就是按照Car的类型来找相对应的bean对象,然后来进行自动赋值,如果太多的话
就报错,如果找不到的话还是赋值null
autowire="constructor:按照构造器进行赋值,如果在类型中有无参构造器的话,他就直接调用无参构造器了,下面的情况是针对有参构造器
1,会先按照参数的类型进行查找,如果找到了一个就直接赋值,如果没有找到的话就赋值null
2,如果找到的是多个的话,就会按照id进行筛选,找到了装配,没有找到的话还是赋值null
3,不会报错
如果需要自动赋值的是列表或者是这种复杂数据类型的一般是使用bytype,然后就会把你所有的创建的(比如book)的bean对象进行赋值到下面的
这个person11里面去了,或者你用byname的话,或许可以试试util:map类似于这种,他的id是可以的
-->
<!-- <bean id="person11" class="com.yxm.entity.Person" autowire="byType"></bean> -->
spel表达式
概念:Spring Expression Language Spring表达式语言
最大的区别是之前的jstl表达式(${})这边这个是#{}
<bean id="person12" class="com.yxm.entity.Person">
<!-- 字面量 -->
<property name="age" value="#{1*18}"></property>
<!-- 引用其它bean -->
<property name="car" value="#{car6}"></property>
<!-- 引用其它bean的属性 -->
<property name="name" value="#{car6.carName}"></property>
<!-- 调用静态方法 -->
<!-- <property name="gender" value="java.util.UUID.randomUUID().toString()"></property> -->
<!-- 调用非静态方法 -->
<property name="gender" value="#{car6.getColor()}"></property>
</bean>