1、spring简介
1.1什么是sping
1.2为什么使用spring(sping的好处)
1.3 spring体系结构
2、核心概念
2.1. IOC
Inversion of Control 控制反转
2.2DI
dependency injection 依赖注入
3.Spring第一个程序
4.IOC容器
IOC容器的两种类型
实例化时机
5.数据装配
6.bean的生命周期:
生命周期的各个阶段:
对生命周期进行扩展:
7.实例化bean的方式
构造方法 有参、无参
静态工厂:无参、有参
实例工厂:无参、有参(非静态方法)
第三方静态工厂
实例工厂
8.Bean的作用域
简介:
9.继承配置
10.自动装配:
介绍:
属性:
11.在Bean中获取容器
简介
一般做法
初始化一个容器做法
12. FactoryBean:
Spring中有两种类型的Bean:
普通的bean ,返回的是bean本身的对象。
FactoryBean
13.Resource
简介:
使用:
14.后(置)处理器:两种
Bean后处理器:
应用场景:
15.BeanFactoryPostProcessor容器后其处理
定义:
执行周期
1、spring简介
1.1什么是sping
- Spring是一个开源的控制反转(IOC)和面向切片(AOP)的容器框架,用来简化企业开发。
- 版本:3.x 4.x 5.x
1.2为什么使用spring(sping的好处)
- 降低组件之间的耦合度、时间软件各层之间的解耦合
- 让代码结构更良好
- 面向接口编程
- 高低原则:高内聚,低耦合
- 开闭原则:对扩展开放、对修改关闭
- 提供了很多辅助类 如:JdbcTemplate StringUtils CollectionUtils StreamUtils
- 提供单利模式
- 提供AOP技术
- 对主流框架集成了支持
- 集成Mybatis、Hibernate、JPA、Struts等支持
1.3 spring体系结构
- IOC
- AOP
- Data Access
- Web
2、核心概念
2.1. IOC
Inversion of Control 控制反转
public class UserServiceImpl{
//UserDao由Service创建和维护
Private UserDao uesrDao=new UserDaoImpl();
public void regist(User user)
{
UserDao.save(user);
}
}
控制反转就是指本身不负责依赖对象的创建和维护、依赖对象的创建及维护交由外部容器来负责,这样控制权就发生了转移,控制权转移就是控制反转。
外部容器/Ioc容器:存储对象(bean)的容器
2.2DI
dependency injection 依赖注入
public class UserServiceImpl{
//UserDao由外部容器创建来维护
Private UserDao uesrDa;
//让容器将创建好的对象注入到service中
public void setUserDao(uesrDao userDao){
this.userDao=userDao
}
public void regist(User user){
userDao.save(user);
}
}
依赖注入就是指在运行期间,由外部容器动态的将依赖对象注入到组件。
3.Spring第一个程序
- spring核心的四个jar包
- spring-core
*spring-beans
*spring-expression
*spring-context
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-core.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-beans.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-context.version}</version>
</dependency>
<!-- spring核心包 expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring-expression.version}</version>
</dependency>
- spring.xml配置文件
<bean class="ioc01.HelloSpring" id="helloSpring">
<property name="name" value="tom"/>
</bean>
*初始化容器
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc01/applicationContext.xml");
HelloSpring hellospring = (HelloSpring) ac.getBean("helloSpring");
hellospring.show();
//输出值:Hello:tom
- 如何注入的值?:
它是通过set方法注入的值。显示new一个无参的构造函数,然后调用set方法赋值。 - 注入再体验
当你在另外一个类里面需要使用其他对象,则需要在spring里面注入其他类。
<bean id="userDao" class="ioc02.dao.impl.UserDaoImpl"/>
<bean id="userService" class="ioc02.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
public interface UserDao {
public User selectbyUser(String username);
}
public class UserDaoImpl implements UserDao{
@Override
public User selectbyUser(String username) {
System.out.println("使用Jdbc查找");
User user=new User();
user.setPassword("123");
user.setUsername(username);
return user;
}
}
public interface UserService {
public boolean login(String username,String password);
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao)
{
this.userDao=userDao;
}
@Override
public boolean login(String username, String password) {
User user=userDao.selectbyUser(username);
if(user!=null)
{
return user.getPassword().equals(password);
}
return false;
}
}
public static void main(String[] args) {
ApplicationContext ap=new ClassPathXmlApplicationContext("ioc02/spring.xml");
UserService userService = (UserService) ap.getBean("userService");
boolean flag = userService.login("zhangsan", "123");
if(flag)
{
System.out.println("success");
}
else{
System.out.println("fail");
}
}
4.IOC容器
IOC容器的两种类型
- ApplicationContext:
ClassPathxmlApplicationContext
FileSystemXmlApplicationContext - BeanFacotry(过时)
XmlBeanFactory
ApplicationContext:
在项目资源目录下可以使用初始化spring文件:
ApplicationContext ap=new ClassPathXmlApplicationContext("ioc03/spring.xml");
如果在在文件目录下可以使用来初始化spring文件
ApplicationContext ap=new FileSystemXmlApplicationContext("F:\\spring.xml");
BeanFacotry:
在类路径下加载spring文件
BeanFactory bf=new XmlBeanFactory(new ClassPathResource("ioc03/spring.xml"));
SpringBean springBeanbf = (SpringBean)bf.getBean("springbean");
System.out.println(springBeanbf);
在系统磁盘下加载:
BeanFactory bffile=new XmlBeanFactory(new FileSystemResource("F:\\spring.xml"));
SpringBean springBeanbffile = (SpringBean)bffile.getBean("springbean");
System.out.println(springBeanbffile);
实例化时机
ApplicationContext
默认预先实例化、及容器启动时候就实例化。实际应用中都是预先实例化,虽然容器启动时候满,但是用户访问速度快
配置lazy-init 为true 则调用getBean时候在实例化。
BeanFactory
只能懒实例化,调用getBean时候才能实例化
5.数据装配
- 定义:
为bean中属性注入值,叫做数据的装配,可装配不同类型的值
装配类型: - 一、简单类型(通过value进行装配):
八种基本类型及包装类
* byte short int long flaot double boolean
* Byte Short Integer Long Float Double Boolean
*String Class Resources - 二、集合类型装配
- 三、 其他bean的引用 使用ref
- 四、赋null值:
简单类型装配:
private int age;
private byte bt;
private double price;
private String username;
private Class classzz;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public byte getBt() {
return bt;
}
public void setBt(byte bt) {
this.bt = bt;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Class getClasszz() {
return classzz;
}
public void setClasszz(Class classzz) {
this.classzz = classzz;
}
<bean class="ioc04.SpringBean" name="springBean">
<property name="age" value="12"/>
<property name="bt" value="4"/>
<property name="price" value="12.4"/>
<property name="username" value="alice"/>
<property name="classzz" value="java.lang.String"/>
</bean>
集合类型装配:
private OtherBean otherbean;
private Integer [] arrays;
private List<OtherBean> lists;
private Set<OtherBean> sets;
private Map<OtherBean,Class> map;
private Properties properties;
public Integer[] getArrays() {
return arrays;
}
public void setArrays(Integer[] arrays) {
this.arrays = arrays;
}
public List<OtherBean> getLists() {
return lists;
}
public void setLists(List<OtherBean> lists) {
this.lists = lists;
}
public Set<OtherBean> getSets() {
return sets;
}
public void setSets(Set<OtherBean> sets) {
this.sets = sets;
}
public Map<OtherBean, Class> getMap() {
return map;
}
public void setMap(Map<OtherBean, Class> map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public OtherBean getOtherbean() {
return otherbean;
}
public void setOtherbean(OtherBean otherbean) {
this.otherbean = otherbean;
}
@Override
public String toString() {
return "SpringBean{" +
"otherbean=" + otherbean +
", arrays=" + Arrays.toString(arrays) +
", lists=" + lists +
", sets=" + sets +
", map=" + map +
", properties=" + properties +
‘}‘;
}
<bean class="ioc05.OtherBean" id="otherBean">
<property name="username" value="toms"/>
</bean>
<bean class="ioc05.SpringBean" id="springBean">
<property name="otherbean" ref="otherBean"/>
<property name="arrays">
<!--array 可以改成list-->
<array>
<value>1</value>
<value>2</value>
<value>5</value>
</array>
</property>
<property name="lists">
<list>
<!--引用上面的bean-->
<ref bean="otherBean"/>
<!--新创建bean-->
<bean class="ioc05.OtherBean">
<property name="username" value="张三"/>
</bean>
<bean class="ioc05.OtherBean">
<property name="username" value="李四"/>
</bean>
</list>
</property>
<property name="sets">
<set>
<!--引用上面的bean-->
<ref bean="otherBean"/>
<ref bean="otherBean"/>
<bean class="ioc05.OtherBean">
<property name="username" value="set集合"/>
</bean>
<bean class="ioc05.OtherBean">
<property name="username" value="set集合数据"/>
</bean>
</set>
</property>
<property name="map">
<map>
<entry key-ref="otherBean" value="java.lang.String"/>
</map>
</property>
<property name="properties">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
<prop key="key3">value3</prop>
</props>
</property>
</bean>
其他bean的引用:
<bean class="ioc05.OtherBean" id="otherBean">
<property name="username" value="toms"/>
</bean>
<bean class="ioc05.SpringBean" id="springBean">
<property name="otherbean" ref="otherBean"/>
</bean>
赋null值:
private String name="alice";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
<bean class="ioc06.SpringBean" id="springBean">
<property name="name" >
<null/>
</property>
</bean>
//值为null
6.bean的生命周期:
生命周期的各个阶段:
代码块->实例化构造函数->数据装配->准备就绪- >使用->销毁
对生命周期进行扩展:
代码块->实例化构造函数->数据装配->初始化(init-method)->准备就绪- >使用->销毁之前执行->销毁
<bean class="ioc07.springBean" id="springBean" init-method="init">
<property name="username" value="spring生命周期"/>
<property name="sex" value="sexvalue"/>
</bean>
public class springBean {
{
System.out.println("这是一个代码块!");
}
private String username;
private String sex;
public springBean() {
System.out.println("springBean.springBean");
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
System.out.println("springBean.setUsername");
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
System.out.println("springBean.setSex");
this.sex = sex;
}
@Override
public String toString() {
return "springBean{" +
"username=‘" + username + ‘\‘‘ +
", sex=‘" + sex + ‘\‘‘ +
‘}‘;
}
public void init()
{
this.username=this.getUsername().toUpperCase()+"_"+this.getSex().toUpperCase();
}
输出语句:
这是一个代码块!
springBean.springBean
springBean.setUsername
springBean.setSex
springBean{username=‘SPRING生命周期_SEXVALUE‘, sex=‘sexvalue‘}
- 练习:
需求:有一个配置文件存放的是用户信息,需要在容器初始化的时候把对应内容注入到bean中
info.propertis
info.username=tom
info.password=passwodtom
[email protected]
info.address="北京市朝阳区"
spring.xml
<bean class="ioc08.springBean" id="springBean" init-method="init">
<property name="username" value="${info.username}"/>
<property name="address" value="${info.address}"/>
<property name="email" value="${info.email}"/>
<property name="password" value="${info.password}"/>
</bean>
springBean.java
public class springBean {
private String username;
private String password;
private String email;
private String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "springBean{" +
"username=‘" + username + ‘\‘‘ +
", password=‘" + password + ‘\‘‘ +
", email=‘" + email + ‘\‘‘ +
", address=‘" + address + ‘\‘‘ +
‘}‘;
}
public void init()
{
this.username = refvalue(this.username);
this.password = refvalue(this.password);
this.email = refvalue(this.email);
this.address = refvalue(this.address);
}
public String refvalue(String value)
{
if(value!=null&&!value.equals(""))
{
if(value.startsWith("${")&&value.endsWith("}"))
{
String key=value.substring(2,value.length()-1);
return getProperty(key);
}
}
return "";
}
public String getProperty(String key)
{
Properties p=new Properties();
try {
p.load(springBean.class.getClassLoader().getResourceAsStream("ioc08/info.properties"));
} catch (IOException e) {
e.printStackTrace();
}
if(p.containsKey(key))
{
return p.getProperty(key);
}
else
{
throw new RuntimeException("not find key");
}
}
7.实例化bean的方式
构造方法 有参、无参
静态工厂:无参、有参
实例工厂:无参、有参(非静态方法)
- 构造方法:
<bean class="ioc09.SpringBean" id="springBean">
<property name="age" value="1"/>
<property name="password" value="passwordvalue"/>
<property name="username" value="usernamevalue"/>
</bean>
<bean class="ioc09.SpringBean" id="springBean2">
<constructor-arg name="age" value="12"/>
<constructor-arg name="password" value="passvalue"/>
<constructor-arg name="username" value="usernamevalue"/>
</bean>
静态工厂:
工厂类:
public static springBean springBean()
{
return new springBean();
}
public static springBean getSpringBean(String name)
{
springBean springBean=new springBean();
springBean.setName(name);
return springBean;
}
属性:
public class springBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
xml:
<!--无参-->
<bean class="ioc10.SpringFactory" id="springFactory" factory-method="springBean">
<property name="name" value="toms"/>
</bean>
<!--带参数-->
<bean class="ioc10.SpringFactory" id="springFactory2" factory-method="getSpringBean">
<constructor-arg name="name" value="toms"/>
</bean>
执行:
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc10/spring.xml");
springBean springFactory = (springBean) ac.getBean("springFactory");
System.out.println(springFactory.getName());
第三方静态工厂
除了自定义的工厂外,可以获取第三方的静态工厂:
bean class="java.util.Calendar" id="calendar" factory-method="getInstance"/>
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc11/spring.xml");
Calendar calendar = (Calendar) ac.getBean("calendar");
System.out.println(calendar.getTime());
实例工厂
public class SpringBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SpringBean{" +
"name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
public class SpringBeanFactory {
public SpringBean getSpringBean()
{
System.out.println("SpringBeanFactory.getSpringBean");
return new SpringBean();
}
public SpringBean getSpringBean(String name)
{
System.out.println("SpringBeanFactory.getSpringBean");
SpringBean springBean=new SpringBean();
springBean.setName("zhangsan");
return springBean;
}
}
<!--实例工厂-->
<!--不带参数-->
<bean class="ioc12.SpringBeanFactory" id="springBeanFactory"/>
<bean id="springBean" factory-bean="springBeanFactory" factory-method="getSpringBean"/>
<!--带参数-->
<bean id="springBean2" factory-bean="springBeanFactory" factory-method="getSpringBean">
<constructor-arg name="name" value="toms"/>
</bean>
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc12/spring.xml");
SpringBean springBean=(SpringBean)ac.getBean("springBean");
System.out.println(springBean);
SpringBean springBean2=(SpringBean)ac.getBean("springBean2");
System.out.println(springBean2);
8.Bean的作用域
简介:
在ioc容器中默认是单例的。单例bean中属性线程是不安全的,多线程同时访问线程是不安全的。让ioc容器设置为非单例的 scope="prototype",如果配置非单例的,则调用的时候在实例化
##scope 作用域取值:
singleton:单例
prototype:非单例
request:同一个请求中单例
session:同一个会话单例
<bean class="ioc15.springBean" id="springBean" scope="prototype">
<property name="username" value="toms"/>
</bean>
9.继承配置
public class otherBean extends ParentBean{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class ParentBean {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class springBean extends ParentBean{
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
<!--继承配置-->
<bean id="parent" abstract="true">
<property name="password" value="123"/>
</bean>
<bean class="ioc16.springBean" id="springBean" parent="parent">
<property name="age" value="18"/>
<property name="username" value="admin"/>
</bean>
<bean class="ioc16.otherBean" id="otherBean" parent="parent">
<property name="username" value="alice"/>
<property name="sex" value="female"/>
</bean>
10.自动装配:
介绍:
IOC容器可以根据bean的名称、类型和构造方法进行注入,称为自动装配。
属性:
autowire:
default:不自动装配
byName:根据属性名自动装配,查找同名的bean
byType:根据属性自动装配,查找同类型的bean,这种如果存在多类型的bean 则会报错(推荐)
constructor:根据构造方法自动装配,同时根据byName和byType自动装配,先按byName 再按byType( 注:此时不是通过setter方法进行装配的,所以这是可以不写setter方法)
public class OtherBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "OtherBean{" +
"name=‘" + name + ‘\‘‘ +‘}‘;
}
}
public class SpringBean {
private OtherBean otherBean;
public OtherBean getOtherBean() {
return otherBean;
}
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
@Override
public String toString() {
return "SpringBean{" +
"otherBean=" + otherBean +
‘}‘;
}
}
// 如果把一个对象的bean自动装在到另外一个bean 不是用property手动装载,则需要使用autowire自动装载
<bean class="ioc17.SpringBean" id="springBean" autowire="byType">
<!-- <property name="otherBean" ref="otherBean"/>-->
</bean>
<bean class="ioc17.OtherBean" id="otherBean">
<property name="name" value="toms"/>
</bean>
<!-- 有两个类型 ioc17.OtherBean的bean 用 byType装载失败-->
<bean class="ioc17.OtherBean" id="otherBean">
<property name="name" value="toms"/>
</bean>public class OtherBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "OtherBean{" +
"name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
public class SpringBean {
private OtherBean otherBean;
public OtherBean getOtherBean() {
return otherBean;
}
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
@Override
public String toString() {
return "SpringBean{" +
"otherBean=" + otherBean +
‘}‘;
}
}
// 如果把一个对象的bean自动装在到另外一个bean 不使用property手动装载,则需要使用autowire自动装载
<bean class="ioc17.SpringBean" id="springBean" autowire="byType">
<!-- <property name="otherBean" ref="otherBean"/>-->
</bean>
<bean class="ioc17.OtherBean" id="otherBean">
<property name="name" value="toms"/>
</bean>
<!-- 有两个类型 ioc17.OtherBean的bean 用 byType装载失败-->
<bean class="ioc17.OtherBean" id="otherBean">
<property name="name" value="toms"/>
</bean>
11.在Bean中获取容器
简介
如果有实体或者静态工具类中获取spirng容器里面的数据。
一般做法
在每个类或者方法里面都要初始化ApplicaitonContext容器才能获取到,但是这样就存在多个容器。
A类:
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc18/spring.xml");
B类:
ApplicationContext ac1=new ClassPathXmlApplicationContext("ioc18/spring.xml");
初始化一个容器做法
spring本身应该是单例模式。所以应该有一个保存容器的类,而不是每次要都在类或者方法里面初始化容器。实际开发中一般只初始化一个容器
- 定义一个ioc容器的工具类实现ApplicationContextAware
public static ApplicationContext ap;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContext.setApplicationContext");
ap=applicationContext;
System.out.println("ApplicationContext.endsetApplicationContext");
}
//这是一种方法,但是很不安全。因为容器启动的时候才会调用setApplicationContext方法赋值,但是如果给apfugei null
//那就所有人都获取不到了。因为这个返回的applicaitonContext对象,如果制定bean 返回bean则安全很多
/* public static ApplicationContext getapplicationContext()
{
return ap;
}*/
//建议使用下面两种方法 都可以
//方法一、
public static Object getBean(String bean)
{
return ap.getBean(bean);
}
方法二:
public static <T> T getBean(Class<T> classz)
{
return ap.getBean(classz);
}
//调用
SpringBean bean = applicationContextHoder.getBean(SpringBean.class);
System.out.println(bean);
return bean.getName();
- 在spirng文件里配置
<!---将工具bean加入到ioc容器中 -->
<bean class="ioc18.applicationContextHoder"/>
12. FactoryBean:
Spring中有两种类型的Bean:
普通的bean ,返回的是bean本身的对象。
<bean class="ioc18.SpringBean" id="springBean">
<property name="name" value="toms"/>
</bean>
- 工厂Bean, 及FactoryBean 。它返回任意类型
FactoryBean
- 应用场景:
如果普通的bean配置比较复杂,在配置文件中步骤比较多,此时可以使用FactoryBean如: 我要去到prepareStatement需要在xml配置这么多。
<bean class="java.lang.Class" id="aClass" factory-method="forName">
<constructor-arg name="className" value="com.mysql.jdbc.Driver"/>
</bean>
<bean class="java.sql.DriverManager" id="driverManager" factory-method="getConnection">
<constructor-arg name="url" value="jdbc:mysql://localhost:3306/ums"/>
<constructor-arg name="user" value="root"/>
<constructor-arg name="password" value="123456"/>
</bean>
<bean class="java.sql.Connection" factory-bean="driverManager" factory-method="prepareStatement" id="prepare">
<constructor-arg name="sql" value="select * from t_user"/>
</bean>
- 解决办法:
定义一个类 实现FactoryBean接口,重写里面方法。
public class prepareStatementFactoryBean implements FactoryBean<PreparedStatement> {
//生成实例的过程
@Override
public PreparedStatement getObject() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/ums","root","123456");
PreparedStatement ps=conn.prepareStatement("select *from users");
return ps;
}
//生成实例的类型
@Override
public Class<?> getObjectType() {
return PreparedStatement.class;
}
//是否单例,true单例 false 非单例,默认不是单例
@Override
public boolean isSingleton() {
return true;
}
}
在spring.xml配置该类
<bean id="ps" class="ioc19.prepareStatementFactoryBean"/>
调用:
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc19/spring.xml");
System.out.println(ac.getBean("ps"));
13.Resource
简介:
本质上就是java.io.File的封装
使用:
根据位置不同,提供了不同的实现类,用来快速获取资源。
ApplicationContext ap=new ClassPathXmlApplicationContext("ioc21/spring.xml");
SpringBean resource = (SpringBean) ap.getBean("resource");
System.out.println(resource.getResource().contentLength());
<bean id="resource" class="ioc21.SpringBean">
<property name="resource" value="file:d:/a.txt"/>
</bean>
14.后(置)处理器:两种
Bean后处理器,实现BeanPostProcessor 接口
BeanFactory后处理器,实现BeanFactoryPostProcess接口,也成为容器后处理器
Bean后处理器:
应用场景:
当对所有bean进行其他处理的时候使用。
Bean后处理器用来丢bean的功能进行扩展增强,对“IOC容器总所有的bean都有效”
##执行周期:
初始化之前和出初始化之后
代码块->实例化->数据装配->(BeanPostProcessor)初始化之前->初始化方法->(BeanPostProcessor)初始化之后->就绪->使用->销毁->从容器中销毁
##实现步骤:
定义一个类,实现BeanPostProcessor
将该处理器添加到ioc容器
以下代码是bean属性值从info.properties 取到的
public class PropertiesBeanPostProcessor implements BeanPostProcessor {
private Resource resource;
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> aClass = bean.getClass();
Field [] files=aClass.getDeclaredFields();
for (Field field:files)
{
Class<?> type=field.getType();
if(type==String.class)
{
String name=field.getName();
System.out.println("name:"+name);
try {
field.setAccessible(true);
String str=field.get(bean).toString();
String refvalue = refvalue(str);
field.setAccessible(true);
field.set(bean,refvalue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return bean;
}
public String refvalue(String value)
{
if(value!=null&&!value.equals(""))
{
if(value.startsWith("${")&&value.endsWith("}"))
{
/* String key=value.substring(2,value.length()-1);
return getProperty(key);*/
Pattern compile = Pattern.compile("\\$\\{(.*)\\}");
Matcher matcher = compile.matcher(value);
if(matcher.matches())
{
String key= matcher.group(1);
return getProperty(key);
}
}
}
return "";
}
public String getProperty(String key)
{
Properties p=new Properties();
try {
p.load(resource.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
if(p.containsKey(key))
{
return p.getProperty(key);
}
else
{
throw new RuntimeException("not find key");
}
}
}
spring.xml
<bean class="ioc23.OtherBean" id="otherBean">
<property name="address" value="${name}"/>
<property name="password" value="${password}"/>
</bean>
<bean class="ioc23.springbean" id="springBean">
<property name="email" value="${email}"/>
<property name="password" value="${password}"/>
<property name="phone" value="${phone}"/>
<property name="username" value="${username}"/>
</bean>
<bean class="ioc23.PropertiesBeanPostProcessor">
<property name="resource" value="classpath:ioc23/info.properties"/>
</bean>
main:
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc23/spring.xml");
OtherBean otherBean = (OtherBean) ac.getBean("otherBean");
springbean springbean= (ioc23.springbean) ac.getBean("springBean");
System.out.println(otherBean);
System.out.println("springBean:"+springbean);
15.BeanFactoryPostProcessor容器后其处理
定义:
容器后处理器在bean创建之前执行 ,修改bean的自定义属性
执行周期
执行周明周期 是在最前面
BeanFactoryPostProcessor->代码块->实例化->数据装配->初始化之前->初始化方法->初始化之后->就绪->使用->销毁->从容器中销毁
##实现步骤
*定义一个类 实现BeanFactoryPostProcessor 或使用spring内置的CustomEditorConfigure
*将该bean添加到IOC容器中
*自定义属性编辑器 PropertyEditor(转换器 ),实现PropertyEdit或者继承 PropertyEditorSupport父类
*在容器后处理器中注册属性编辑器
spring.xml
<property name="address" value="[北京-朝阳]"/>
<property name="birthday" value="1989-08-21"/>
<property name="username" value="${info.username}"/>
<property name="sex" value="${info.sex}"/>
</bean>
<!-- <bean class="ioc24.SpringBeanFactoryProcessor">
<property name="customEditor">
<map>
<entry key="ioc24.Address" value="ioc24.editor.AddressEditor"/>
<entry key="java.util.Date" value="ioc24.editor.DateEdit"/>
<entry key="java.lang.String" value="ioc24.editor.StringEdit"/>
<entry key="java.lang.Boolean" value="ioc24.editor.BooleaEdit"/>
</map>
</property>
</bean>-->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer" id="configurer">
<property name="customEditors">
<map>
<entry key="ioc24.Address" value="ioc24.editor.AddressEditor"/>
<entry key="java.util.Date" value="ioc24.editor.DateEdit"/>
<!-- <entry key="java.lang.String" value="ioc24.editor.StringEdit"/>
<entry key="java.lang.Boolean" value="ioc24.editor.BooleaEdit"/>-->
</map>
</property>
</bean>
<!-----------spring提供的PropertySourcesPlaceholderConfigurer 内置了匹配查找方法,可以不用自己写------------------>
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:ioc24/info.properties"/>
</bean>
<bean class="java.util.Properties" id="properties"/>
</beans>
自定义属性编辑器
public class AddressEditor extends PropertyEditorSupport {
//获取内容作文文本
@Override
public String getAsText() {
System.out.println("getAsText:"+getValue());
Address address=(Address)getValue();
String city="["+address.getCity()+"-"+address.getProvince()+"]";
System.out.println(city);
return city;
}
//将字符串转换为对象
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("text:"+text);
Pattern pattern = Pattern.compile("\\[(.*)-(.*)\\]");
Matcher matcher=pattern.matcher(text);
if(matcher.matches())
{
String city=matcher.group(1);
System.out.println("city:"+city);
String province=matcher.group(2);
System.out.println("province:"+province);
Address address=new Address();
address.setCity(city);
address.setProvince(province);
//调用setValue获取值
setValue(address);
}
}
public class SpringBeanFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("SpringBeanFactoryProcessor.SpringBeanFactoryProcessor");
System.out.println("beanFactory:"+beanFactory);
//像容器中注册属性编辑器,第一个参数表示要转换的属性类型,第二个参数表示要使用的属性编辑器
try {
beanFactory.registerCustomEditor(Address.class, AddressEditor.class);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
原文地址:https://www.cnblogs.com/lilihai/p/ba73f4a5ce59568c416da358ebc0ba90.html