您的位置:首页 > 编程语言 > Java开发

Spring学习笔记01-自动装配-SpEL-生命周期-后置处理器(未完)

2017-03-05 16:10 706 查看
在p命名空间中,-ref 后缀作为一个标识来告知Spring 应该装配一个引用而不是字面值。

自动装配:

可以用autowire属性指定自动装配的方式:

可以用autowire属性指定自动装配的方式

可以用autowire属性指定自动装配的方式
byname 根据bean的名字和当前bean的setter风格的属性名进行自动装配,若有匹配的,则进行自动装配,若没有匹配的,则不进行装配;
bytype根据bean的类型和当前bean的属性的类型进行自动的装配.若IOC容器中有1个以上的匹配的bean,则抛异常.
通过构造器装配 ,不推荐使用;
自动装配的缺点:1.在 Bean 配置文件里设置 autowire 属性进行自动装配将会装配 Bean 的所有属性. 然而, 若只希望装配个别属性时, autowire 属性就不够灵活了.
2.autowire 属性要么根据类型自动装配, 要么根据名称自动装配, 不能两者兼而有之.
注意:一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些,有的时候,在整合第三方框架的时,使用自动装配能给我们带来一点方便;


<bean id="address" class="com.spring.autowire.Address" p:city="sichuan" p:street="Huihogguan"></bean>
<bean id="car" class="com.spring.autowire.Car" p:brand="auti" p:price="3000"></bean>
<!--这里就是自动装配属性 -->
<bean id="person" class ="com.spring.autowire.Person" p:name="Tom" autowire="byName"></bean>


继承 Bean 配置:

bean配置的继承:使用bean的parent属性指定继承哪个bean的配置 .不会继承abstract ,autowire.
抽象bean:bean的abstract属性为true的bean,这样的bean不能被IOC容器实例化,只用来被继承配置.
若某一个bean的class属性没有指定,则该bean必须是一个抽象bean.


depend-on前置依赖不是很懂;

bean的作用域(scope),(默认的作用域为单例的):

​ prototype不是单例的;

​ singleton:默认值,容器创建bean实例,在整个容器的生命周期内只创建这一个bean.单例的;

​ prototype:原型的,容器初始时不创建bean实例,而在每次请求时都创建一个新的bean实例,并返回;

spring_使用外部文件:

​ 首先导入c3p0.jar和mysql数据库连接的架包;

​ bean的配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///test"></property><!-- 这里为什么是三个斜杠?? -->
</bean>


​ java的配置:

public static void main(String[] a){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-config.xml");
DataSource datasource = (DataSource)ctx.getBean("dataSource");
try {
System.out.println(datasource.getConnection());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


上面是在bean中配置数据源,接下来在外部文件中配置数据源:

在bean的容器中:

需要加入下面一行语法:

<!-- 导入属性文件 -->
<context:property-placeholder location="classpath:db.properties"/><!-- 用于使用外部属性文件的-->


​ 还有底下的语句:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property><!--${}里面是properties文件中的属性名  -->
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverclass}"></property>
<property name="jdbcUrl" value="${jdbcurl}"></property><!-- 这里为什么是三个斜杠!! -->
</bean>


​ 还要建立一个以.properties为后缀的文件:

user=root
password=123456
driverclass=com.mysql.jdbc.Driver
jdbcurl=jdbc:mysql:///test


以上就好了,其余的配置和前面的一样;

———————————–这是一条分隔线———————————————–

spring的表达式语言:

​ spEL:是一个支持运行时查询和操作对象图的强大的表达式语言。

​ •语法类似于EL:SpEL使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是SpEL

​ •SpEL为 bean的属性进行动态赋值提供了便利

​ •通过 SpEL可以实现:

​ –通过 bean 的id对bean进行引用

​ –调用方法以及引用对象中的属性

​ –计算表达式的值

​ –正则表达式的匹配

spring的字面值:



字面量的表示:
整数:<property name="count" value="#{5}"/>
小数:<property name="frequency" value="#{89.7}"/>
科学计数法:<property name="capacity" value="#{1e4}"/>
String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/>
Boolean:<property name="enabled" value="#{false}"/>


SpEL:(引用Bean、属性和方法):

说明以下的都是图片

​ 引用其他对象:







​ 调用静态方法或静态属性:通过T() 调用一个类的静态方法,它将返回一个Class Object,然后再调用相应的方法或属性:

<bean id="car" class="com.spring.autowire.spel.Car">
<property name="brand" value="Audi"></property>
<property name="price" value="500000"></property>
<!--  下面的使用spel引用类的静态属性 -->
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI * 80}"></property>
</bean>


下面是一个例子(关于bean):

<bean id="person" class="com.spring.autowire.spel.Person">
<!-- 使用spel来应用其他的bean -->
<property name="car" value="#{car}"></property>
<!--使用spel来应用其他的bean的属性  -->
<property name="city" value="#{address.city}"></property>
<!-- 在spel中使用运算符 -->
<property name="info" value="#{car.price > 300000 ? '金领':'白领'}"></property>
</bean>


—————————这是一条分隔线————————————————————————-

IOC 容器中 Bean的生命周期方法:

​ •Spring IOC 容器可以管理 Bean 的生命周期,Spring 允许在 Bean 生命周期的特定点执行定制的任务.

​ •Spring IOC 容器对 Bean的生命周期进行管理的过程:

​ –1.通过构造器或工厂方法创建 Bean实例

​ –2.为 Bean 的属性设置值和对其他Bean的引用

​ –3.调用 Bean的初始化方法

​ –4.Bean 可以使用了

​ –5.当容器关闭时,调用 Bean的销毁方法

•在 Bean 的声明里设置init-method和destroy-method属性,为Bean指定初始化和销毁方法.

具体实例:

​ bean的配置:

<bean id="car" class="com.spring.bean.cycle.Car"
init-method="init"
destroy-method="destroy">
<property name="brand" value="auto"></property>
</bean>


主main中的代码:

//ApplicationContext接口有一个子接口(ConfigurableApplicationContext这个接口里面有close的方法)
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-cycle.xml");
Car car = (Car) ctx.getBean("car");
System.out.println(car);
ctx.close();


java代码:



package com.spring.bean.cycle;

public class Car {
public Car(){
System.out.println("Car 的构造器!!!");
}
private String brand;
public void setBrand(String brand){
System.out.println("setBrand...");
this.brand  = brand;
}
public String getBrand() {
return brand;
}
public void init(){  //初始化的方法
System.out.println("init...");
}
public void destroy(){  //关闭ioc容器要调用的销毁的方法;
System.out.println("destroy...");
}
}


注意:在bean的配置中声明了init-method和destroy-method属性,其中的属性值就是在class类中的方法名,所以在class所指定的类中必须要有初始化和销毁的方法;

更细致的控制(bean的后置处理器):

​ ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。

创建bean的后置处理器:

​ •Bean 后置处理器允许在调用初始化方法前后对Bean 进行额外的处理.

​ •Bean 后置处理器对IOC 容器里的所有Bean 实例逐一处理,而非单一实例.其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性.

​ •对Bean 后置处理器而言,需要实现org.springframework.beans.factory.config.BeanPostProcessor接口.

在初始化方法被调用前后,Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:

1,postProcessAfterInitialization()

2,postProcessBeforeInitalization()

bean配置的代码:

​ 注意:1.中间加入的bean的后置处理器代码,2.一个后置处理器管理在其声明处的beans中的所有bean在实例化时都要调用后置处理器;

<bean id="car" class="com.spring.bean.cycle.Car"
init-method="init"
destroy-method="destroy" ><!-- 属性值init和destroy可以不相同,只要和Car中的初始化方法名一样就可以了 -->
<property name="brand" value="auto"></property>
</bean>

<!--
实现BeanPostProcessor接口,并具体提供两个方法的实现:
方法一:public Object postProcessAfterInitialization(Object arg0, String arg1) (此方法在init-method之 前 被调用);
方法二:public Object postProcessBeforeInitialization(Object arg0, String arg1)(此方法在init-method之 后 被调用);
-----------这是一个调皮的分隔线------------
bean:bean实例本身;
beanName:IOC容器配置bean的名字.
返回值:是实际上返回给用户的那个Bean,注意:可以在以上两个方法中修改返回的bean,甚至可以返回一个新的bean;, -->
<!-- 配置Bean的后置处理器 ,不需要配置id,IOC容器自动识别是一个BeanPostProcessor-->
<bean class="com.spring.bean.cycle.MyBeanProcesssor"></bean>


bean的后置处理器其实是一个实现的特定接口的类:

​ 代码如下:

//后置处理器要实现的接口
public class MyBeanProcesssor implements BeanPostProcessor{
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
// TODO Auto-generated method stub
System.out.println("PostProcessAfterInitialization");
return arg0;
}

@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
// TODO Auto-generated method stub
System.out.println("PostProcessBeforeInitialization");
return arg0;
}
}


零碎的知识点补充:

​ 1.ClassPathXmlApplicationContext的意思是在类路径中寻找xml配置文件,找到并加载;

​ 2.FileSystemXmlApplicationContext的意思是在文件系统路径中寻找xml配置文件,找到并加载;

​ 3.在ApplicationContext实例化后,同样通过getBean方法从ApplicationContext容器中获取装配好的Bean实例以供使用;

​ 4.在Java项目中通过ClassPathXmlApplicationContext类手动实例化ApplicationContext容器通常是不二之选。但对于Web项目就不行了,Web项目的启动是由相应的Web服务器负责的,因此,在Web项目中ApplicationContext容器的实例化工作最好交给Web服务器来完成。

————————————————这是一条分割线,回顾以前————————————–



————————————————这是一条分割线,回顾以前————————————–
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring bean