Spring框架介绍及使用

Posted lilihai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架介绍及使用相关的知识,希望对你有一定的参考价值。

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;">





以上是关于Spring框架介绍及使用的主要内容,如果未能解决你的问题,请参考以下文章

01---Spring框架

Spring框架介绍及使用

CXF框架介绍及Spring集成

系统开发系列 之WebService(spring框架+maven+CXF框架)部署问题及解决方案

系统开发系列 之WebService(spring框架+maven+CXF框架)部署问题及解决方案

Spring介绍及配置(XML文件配置和注解配置)