spring框架技术学习

spring入门

 <!--
        老韩解读
        1. 配置monster对象/javabean
        2. 在beans中可以配置多个bean
        3. bean表示就是一个java对象
        4. class属性是用于指定类的全路径->spring底层使用反射创建
        5. id属性表示该java对象在spring容器中的id, 通过id可以获取到对象
        6. <property name="monsterId" value="100"> 用于给该对象的属性赋值
    -->
    <bean class="com.hspedu.spring.bean.Monster" id="monster01">
        <property name="monsterId" value="100"/>
        <property name="name" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>

    <bean class="com.hspedu.spring.bean.Monster" id="monster02">
        <property name="monsterId" value="1001"/>
        <property name="name" value="牛魔王~"/>
        <property name="skill" value="芭蕉扇~"/>
    </bean>
package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 * JavaBean / Entity
 */
public class Monster {
    private Integer monsterId;
    private String name;
    private String skill;

    //全参构造器
    public Monster(Integer monsterId, String name, String skill) {
        this.monsterId = monsterId;
        this.name = name;
        this.skill = skill;
    }


    //无参构造器一定要写,Spring反射创建对象时,需要使用
    public Monster() {
    }

    public Integer getMonsterId() {
        return monsterId;
    }

    public void setMonsterId(Integer monsterId) {
        this.monsterId = monsterId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "monsterId=" + monsterId +
                ", name='" + name + '\'' +
                ", skill='" + skill + '\'' +
                '}';
    }


}

 @Test
    public void getMonster() {

        //老师解读
        //1. 创建容器 ApplicationContext
        //2. 该容器和容器配置文件关联
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        //3. 通过getBean获取对应的对象
        //   默认返回的是Object , 但是运行类型Monster
        //Object monster01 = ioc.getBean("monster01");
        Monster monster01 = (Monster) ioc.getBean("monster01");

        //4. 输出
        System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass());
        System.out.println("monster01=" + monster01 + "属性name=" + monster01.getName() +
                " monserid=" + monster01.getMonsterId());


        //5. 也可以再获取的时候,直接指定Class类型, 可以在次获取
        Monster monster011 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster011=" + monster011);
        System.out.println("monster011.name=" + monster011.getName());


        //6. 查看容器注入了哪些bean对象,会输出bean的id
        System.out.println("================================");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName=" + beanDefinitionName);
        }
        System.out.println("================================");

        System.out.println("ok~~~");
    }

 @Test
    public void getMonster() {

        //老师解读
        //1. 创建容器 ApplicationContext
        //2. 该容器和容器配置文件关联
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        //3. 通过getBean获取对应的对象
        //   默认返回的是Object , 但是运行类型Monster
        //Object monster01 = ioc.getBean("monster01");
        Monster monster01 = (Monster) ioc.getBean("monster01");

        //4. 输出
        System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass());
        System.out.println("monster01=" + monster01 + "属性name=" + monster01.getName() +
                " monserid=" + monster01.getMonsterId());


        //5. 也可以再获取的时候,直接指定Class类型, 可以在次获取
        Monster monster011 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster011=" + monster011);
        System.out.println("monster011.name=" + monster011.getName());


        //6. 查看容器注入了哪些bean对象,会输出bean的id
        System.out.println("================================");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName=" + beanDefinitionName);
        }
        System.out.println("================================");

        System.out.println("ok~~~");
    }

配置bean对象

 <!--配置Monster,通过类型来获取-->
    <bean class="com.hspedu.spring.bean.Monster">
        <!--老韩解读
        1.当我们给某个bean对象设置属性的时候
        2.底层是使用对应的setter方法完成的, 比如setName()
        3.如果没有这个方法,就会报错
        -->
        <property name="monsterId" value="100"/>
        <property name="name" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>

    <!--<bean class="com.hspedu.spring.bean.Monster">-->
    <!--    <property name="monsterId" value="200"/>-->
    <!--    <property name="name" value="牛魔王~"/>-->
    <!--    <property name="skill" value="芭蕉扇~"/>-->
    <!--</bean>-->
 @Test
    public void getBeanByType() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        //老师解读,直接传入class对象/类型
        Monster bean = ioc.getBean(Monster.class);
        System.out.println("bean=" + bean);
    }


指定构造器配置

 <!--配置Monster对象,并且指定构造器

    老师解读
    1. constructor-arg标签可以指定使用构造器的参数
    2. index表示构造器的第几个参数 从0开始计算的
    3. 除了可以通过index 还可以通过 name / type 来指定参数方式
    4. 解除大家的疑惑, 类的构造器,不能有完全相同类型和顺序的构造器,所以可以通过type来指定
    -->

    <bean id="monster03" class="com.hspedu.spring.bean.Monster">
        <constructor-arg value="200" index="0"/>
        <constructor-arg value="白骨精" index="1"/>
        <constructor-arg value="吸人血" index="2"/>
    </bean>

    <bean id="monster04" class="com.hspedu.spring.bean.Monster">
        <constructor-arg value="200" name="monsterId"/>
        <constructor-arg value="白骨精" name="name"/>
        <constructor-arg value="吸人血" name="skill"/>
    </bean>


    <bean id="monster05" class="com.hspedu.spring.bean.Monster">
        <constructor-arg value="300" type="java.lang.Integer"/>
        <constructor-arg value="白骨精~" type="java.lang.String"/>
        <constructor-arg value="吸人血~" type="java.lang.String"/>
    </bean>
 @Test
    public void setBeanByConstructor() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        Monster monster03 = ioc.getBean("monster03", Monster.class);
        System.out.println("monster03=" + monster03);
    }

通过p来配置对象

<!--通过p名称空间来配置bean
        老韩解读
        1. 将光标放在p , 输入alt+enter , 就会自动的添加xmlns
        2. 有时需要多来几次
    -->
    <bean id="monster06" class="com.hspedu.spring.bean.Monster"
          p:monsterId="500"
          p:name="红孩儿"
          p:skill="吐火"
    />

给数组对象赋值配置

package com.hspedu.spring.bean;

import java.util.*;

/**
 * @author 韩顺平
 * @version 1.0
 * Master类
 */
public class Master {

    private String name;//主人名

    private List<Monster> monsterList;
    private Map<String, Monster> monsterMap;
    private Set<Monster> monsterSet;

    //数组
    private String[] monsterName;

    //Java基础
    //这个Properties 是 Hashtable的子类 , 是key-value的形式
    //这里Properties  key和value 都是String
    private Properties pros;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Monster> getMonsterList() {
        return monsterList;
    }

    public void setMonsterList(List<Monster> monsterList) {
        this.monsterList = monsterList;
    }

    public Map<String, Monster> getMonsterMap() {
        return monsterMap;
    }

    public void setMonsterMap(Map<String, Monster> monsterMap) {
        this.monsterMap = monsterMap;
    }

    public Set<Monster> getMonsterSet() {
        return monsterSet;
    }

    public void setMonsterSet(Set<Monster> monsterSet) {
        this.monsterSet = monsterSet;
    }

    public String[] getMonsterName() {
        return monsterName;
    }

    public void setMonsterName(String[] monsterName) {
        this.monsterName = monsterName;
    }

    public Properties getPros() {
        return pros;
    }

    public void setPros(Properties pros) {
        this.pros = pros;
    }

    @Override
    public String toString() {
        return "Master{" +
                "name='" + name + '\'' +
                ", monsterList=" + monsterList +
                ", monsterMap=" + monsterMap +
                ", monsterSet=" + monsterSet +
                ", monsterName=" + Arrays.toString(monsterName) +
                ", pros=" + pros +
                '}';
    }
}

</bean>
    <bean class="com.hspedu.spring.bean.Master" id="master">
        <property name="name" value="太上老君"/>
        <property name="monsterList">
            <list>
                <ref bean="monster01"/>
                <ref bean="monster02"/>
                <bean class="com.hspedu.spring.bean.Monster">
                    <property name="name" value="老鼠精"/>
                    <property name="monsterId" value="100"/>
                    <property name="skill" value="吃粮食"/>
                 </bean>
            </list>

        </property>
        <property name="monsterMap">
            <map>
                <entry>
                    <key>
                        <value>
                            monster
                        </value>
                    </key>
                    <ref bean="monster03"/>
                </entry>
                <entry>
                    <key>
                        <value>monster4</value>
                    </key>
                    <ref bean="monster04"/>
                </entry>
            </map>
        </property>
        <property name="monsterSet">
            <set>
                <ref bean="monster05"/>
                <ref bean="monster06"/>
                <bean class="com.hspedu.spring.bean.Monster">
                    <property name="name" value="金角大王"/>
                    <property name="skill" value="吐水"/>
                    <property name="monsterId" value="666"/>
                </bean>
            </set>
        </property>
        <property name="monsterName">
            <array>
                <value>小妖怪</value>
                <value>小妖怪</value>
                <value>小妖怪</value>
            </array>
        </property>
        <property name="pros">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
                <prop key="id">127.0.1</prop>
            </props>
        </property>
 @Test
    public void setBeanByRef() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        MemberServiceImpl memberService =
                ioc.getBean("memberService", MemberServiceImpl.class);

        memberService.add();

    }
master=Master{name='太上老君', monsterList=[Monster{monsterId=100, name='牛魔王', skill='芭蕉扇'}, Monster{monsterId=1001, name='牛魔王~', skill='芭蕉扇~'}, Monster{monsterId=100, name='老鼠精', skill='吃粮食'}], monsterMap={
                            monster
                        =Monster{monsterId=200, name='白骨精', skill='吸人血'}, monster4=Monster{monsterId=200, name='白骨精', skill='吸人血'}}, monsterSet=[Monster{monsterId=300, name='白骨精~', skill='吸人血~'}, Monster{monsterId=500, name='红孩儿', skill='吐火'}, Monster{monsterId=666, name='金角大王', skill='吐水'}], monsterName=[小妖怪, 小妖怪, 小妖怪], pros={password=123456, username=root, id=127.0.1}}


Process finished with exit code 0

通过ref配置对象

<bean class="com.hspedu.spring.dao.MemberDAOImpl" id="memberDAO"/>
    <bean class="com.hspedu.spring.service.MemberServiceImpl" id="memberService">
        <property name="memberDAO" ref="memberDAO"/>
    </bean>
package com.hspedu.spring.dao;

/**
 * @author 韩顺平
 * @version 1.0
 * DAO对象
 */
public class MemberDAOImpl {
    //构造器...
    public MemberDAOImpl() {
        //System.out.println("MemberDAOImpl 构造器被执行...");
    }

    //方法
    public void add() {

        System.out.println("MemberDAOImpl add()方法被执行");
    }
}

package com.hspedu.spring.service;

import com.hspedu.spring.dao.MemberDAOImpl;

/**
 * @author 韩顺平
 * @version 1.0
 * Service类
 */
public class MemberServiceImpl {

    private MemberDAOImpl memberDAO;

    public MemberServiceImpl() {
        //System.out.println("MemberServiceImpl() 构造器被执行");
    }

    public MemberDAOImpl getMemberDAO() {
        return memberDAO;
    }

    public void setMemberDAO(MemberDAOImpl memberDAO) {
        //System.out.println("setMemberDAO()...");
        this.memberDAO = memberDAO;
    }

    public void add() {
        System.out.println("MemberServiceImpl add() 被调用..");
        memberDAO.add();
    }
}

通过内部类配置

 </bean>
    <bean class="com.hspedu.spring.service.MemberServiceImpl" id="memberService2">
        <property name="memberDAO">
            <bean class="com.hspedu.spring.dao.MemberDAOImpl"/>
        </property>
    </bean>

读取数组

package com.hspedu.spring.bean;

import java.util.List;

/**
 * @author 韩顺平
 * @version 1.0
 * 书店类
 */
public class BookStore {
    //书
    private List<String> bookList;

    //无参构造器,如果你没有其它的构造器,该无参构造器可以不写
    //但是如果你有其它的构造器,则必须显式的定义一下无参构造器
    public BookStore() {
    }

    public List<String> getBookList() {
        return bookList;
    }

    public void setBookList(List<String> bookList) {
        this.bookList = bookList;
    }

    @Override
    public String toString() {
        return "BookStore{" +
                "bookList=" + bookList +
                '}';
    }
}

  <util:list id="mybooklist">
        <value>三国演义</value>
        <value>红楼梦</value>
        <value>西游记</value>
        <value>水浒传</value>
    </util:list>
    <bean class="com.hspedu.spring.bean.BookStore" id="bookStore">
    <property name="bookList" ref="mybooklist"/>

级联赋值

 @Test
    public void setBeanByRelation() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        Emp emp = ioc.getBean("emp", Emp.class);
        System.out.println("emp=" + emp);

    }
 </bean>
    <bean class="com.hspedu.spring.bean.Dept" id="dept"/>
    <bean class="com.hspedu.spring.bean.Emp" id="emp">
        <property name="name" value="jack"/>
        <property name="dept" ref="dept"/>
        <property name="dept.name" value="java"/>
    </bean>
package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 * 部门类
 */
public class Dept {
    private String name;

    public Dept() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "name='" + name + '\'' +
                '}';
    }
}

package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 * 员工类
 */
public class Emp {
    private String name;
    private Dept dept;

    public Emp() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "name='" + name + '\'' +
                ", dept=" + dept +
                '}';
    }
}

通过工厂获得类

  //通过静态工厂获取bean
//    //Java基础-静态和非静态
    @Test
    public void getBeanByStaticFactory() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        Monster my_monster01 = ioc.getBean("my_monster01", Monster.class);
        Monster my_monster04 = ioc.getBean("my_monster04", Monster.class);
        System.out.println("my_monster01=" + my_monster01);
        System.out.println(my_monster01 == my_monster04);//true

    }
<bean id="my_monster05" class="com.hspedu.spring.factory.MyFactoryBean">
        <property name="key" value="monster04"/>
    </bean>

    <bean class="com.hspedu.spring.factory.MyInstanceFactory" id="myInstanceFactory"/>
    <bean class="com.hspedu.spring.factory.MyInstanceFactory" id="myInstanceFactory2"/>

    <bean id="my_monster02" factory-bean="myInstanceFactory" factory-method="getMonster">
        <constructor-arg value="monster03"/>
    </bean>

    <bean id="my_monster03" factory-bean="myInstanceFactory2" factory-method="getMonster">
        <constructor-arg value="monster03"/>
    </bean>

    <bean id="my_monster04"
          class="com.hspedu.spring.factory.MyStaticFactory"
          factory-method="getMonster">
        <constructor-arg value="monster02"/>
    </bean>

    <bean id="my_monster01" class="com.hspedu.spring.factory.MyStaticFactory"
     factory-method="getMonster">
        <constructor-arg value="monster02"/>

package com.hspedu.spring.factory;

import com.hspedu.spring.bean.Monster;
import org.springframework.beans.factory.FactoryBean;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 韩顺平
 * @version 1.0
 * 是一个FactoryBean
 */
public class MyFactoryBean implements FactoryBean<Monster> {

    //这个就是你配置时候,指定要获取的对象对应key
    private String key;
    private Map<String, Monster> monster_map;

    {   //代码块,完成初始化
        monster_map = new HashMap<>();
        monster_map.put("monster03", new Monster(300, "牛魔王~", "芭蕉扇~"));
        monster_map.put("monster04", new Monster(400, "狐狸精~", "美人计~"));
    }

    public void setKey(String key) {
        this.key = key;
    }

    @Override
    public Monster getObject() throws Exception {
        return monster_map.get(key);
    }

    @Override
    public Class<?> getObjectType() {
        return Monster.class;
    }

    @Override
    public boolean isSingleton() {//这里指定是否返是单例
        return false;
    }
}

package com.hspedu.spring.factory;

import com.hspedu.spring.bean.Monster;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 韩顺平
 * @version 1.0
 * 实例工厂类
 */
public class MyInstanceFactory {
    private Map<String, Monster> monster_map;

    //通过普通代码块进行初始化
    {
        monster_map = new HashMap<>();
        monster_map.put("monster03", new Monster(300, "牛魔王~", "芭蕉扇~"));
        monster_map.put("monster04", new Monster(400, "狐狸精~", "美人计~"));
    }

    //写一个方法返回Monster对象
    public Monster getMonster(String key) {
        return monster_map.get(key);
    }
}

package com.hspedu.spring.factory;

import com.hspedu.spring.bean.Monster;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 韩顺平
 * @version 1.0
 * 静态工厂类-可以返回Monster对象
 */
public class MyStaticFactory {
    private static Map<String, Monster> monsterMap;

    //使用 static代码块 进行初始化
    //在java基础的时候,讲过的
    static  {
        monsterMap = new HashMap<>();
        monsterMap.put("monster01", new Monster(100,"牛魔王","芭蕉扇"));
        monsterMap.put("monster02", new Monster(200,"狐狸精","美人计"));
    }

    //提供一个方法,返回Monster对象
    public static Monster getMonster(String key) {
        return monsterMap.get(key);
    }

}

通过继承配置

@Test
    public void getBeanByExtends() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        Monster monster11 = ioc.getBean("monster11", Monster.class);
        System.out.println("monster11=" + monster11);

        Monster monster13 = ioc.getBean("monster13", Monster.class);
        System.out.println("monster13=" + monster13);


    }
 <bean id="monster10" class="com.hspedu.spring.bean.Monster">
        <property name="monsterId" value="10"/>
        <property name="name" value="蜈蚣精"/>
        <property name="skill" value="蜇人"/>
    </bean>
    <bean id="monster11"
          class="com.hspedu.spring.bean.Monster"
          parent="monster10"/>

 <bean id="monster12" class="com.hspedu.spring.bean.Monster" abstract="true">
        <property name="monsterId" value="100"/>
        <property name="name" value="蜈蚣精~"/>
        <property name="skill" value="蜇人~"/>
    </bean>

    <bean id="monster13" class="com.hspedu.spring.bean.Monster" parent="monster12"/>

验证执行顺序

  @Test
    public void testBeanByCreate() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        System.out.println("ok");

    }
<bean id="student01" class="com.hspedu.spring.bean.Student" depends-on="department01"/>
    <bean id="department01" class="com.hspedu.spring.bean.Department"/>

测试scope

 @Test
    public void testBeanScope() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        Cat cat = ioc.getBean("cat", Cat.class);
        Cat cat2 = ioc.getBean("cat", Cat.class);
        Cat cat3 = ioc.getBean("cat", Cat.class);
        System.out.println("cat=" + cat);
        System.out.println("cat2=" + cat2);
        System.out.println("cat3=" + cat3);

    }
package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 */
public class Cat {
    private Integer id;
    private String name;

    public Cat() {
        //System.out.println("Cat() 被执行...");
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //@Override
    //public String toString() {
    //    return "Cat{" +
    //            "id=" + id +
    //            ", name='" + name + '\'' +
    //            '}';
    //}
}

 <bean id="cat" class="com.hspedu.spring.bean.Cat" scope="prototype" lazy-init="false">
        <property name="id" value="100"/>
        <property name="name" value="小花猫"/>
    </bean>

测试容器生命周期

  @Test
    public void testBeanLife() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        House house = ioc.getBean("house", House.class);

        System.out.println("使用house=" + house);

        //关闭容器
        //1. 这里又要考察大家的java基础
        //2. ioc的编译类型 ApplicationContext , 运行类型 ClassPathXmlApplicationContext
        //3. 因为ClassPathXmlApplicationContext 实现了 ConfigurableApplicationContext
        //4. ClassPathXmlApplicationContext 是有close
        //5. 将ioc 转成ClassPathXmlApplicationContext,再调用close
        //ioc.close();
        //关闭ioc容器.
        ((ConfigurableApplicationContext) ioc).close();


    }
<bean class="com.hspedu.spring.bean.Monster" id="monster1000">
        <property name="monsterId" value="${monsterId}"/>
        <property name="skill" value="${skill}"/>
        <property name="name" value="${name}"/>
    </bean>
    <bean class="com.hspedu.spring.bean.House" id="house"
          init-method="init"
          destroy-method="destroy">
        <property name="name" value="北京豪宅"/>
    </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"
       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 https://www.springframework.org/schema/context/spring-context.xsd">


    <!--配置House对象-->
    <bean class="com.hspedu.spring.bean.House" id="house"
          init-method="init"
          destroy-method="destroy">
        <property name="name" value="大豪宅"/>
    </bean>

    <bean class="com.hspedu.spring.bean.House" id="house02"
          init-method="init"
          destroy-method="destroy">
        <property name="name" value="香港豪宅"/>
    </bean>

    <!--配置了一个Monster对象-->

    <!--配置后置处理器对象
    老师解读
    1. 当我们在beans02.xml 容器配置文件 配置了 MyBeanPostProcessor
    2. 这时后置处理器对象,就会作用在该容器创建的Bean对象
    3. 已经是针对所有对象编程->切面编程AOP
    -->
    <bean class="com.hspedu.spring.bean.MyBeanPostProcessor" id="myBeanPostProcessor"/>

</beans>
package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 */
public class House {
    private String name;

    public House() {
        System.out.println("House() 构造器...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("House setName()=" + name);
        this.name = name;
    }

    //老师解读
    //1. 这个方法是程序员来编写的.
    //2. 根据自己的业务逻辑来写.
    public void init() {
        System.out.println("House init()..");
    }

    //老师解读
    //1. 这个方法是程序员来编写的.
    //2. 根据自己的业务逻辑来写.
    //3. 名字也不是固定的
    public void destroy() {
        System.out.println("House destroy()..");
    }

    @Override
    public String toString() {
        return "House{" +
                "name='" + name + '\'' +
                '}';
    }
}

@Test
    public void testBeanPostProcessor() {

        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans02.xml");

        House house = ioc.getBean("house", House.class);
        System.out.println("使用house=" + house);

        House house02 = ioc.getBean("house02", House.class);
        System.out.println("使用house02=" + house02);

        ((ConfigurableApplicationContext)ioc).close();

    }
House() 构造器...
House setName()=大豪宅
postProcessBeforeInitialization().. bean=House{name='大豪宅'} beanName=house
House setName()=上海豪宅~
House init()..
postProcessAfterInitialization().. bean=House{name='上海豪宅~'} beanName=house
House() 构造器...
House setName()=香港豪宅
postProcessBeforeInitialization().. bean=House{name='香港豪宅'} beanName=house02
House setName()=上海豪宅~
House init()..
postProcessAfterInitialization().. bean=House{name='上海豪宅~'} beanName=house02
使用house=House{name='上海豪宅~'}
使用house02=House{name='上海豪宅~'}
House destroy()..
House destroy()..

自动装配

<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置OrderDao对象-->
    <bean class="com.hspedu.spring.dao.OrderDao" id="orderDao"/>
    <!--配置OrderService对象
        老师解读
        1. autowire="byType" 表示 在创建 orderService时
           通过类型的方式 给对象属性 自动完成赋值/引用
        2. 比如OrderService 对象有 private OrderDao orderDao
        3. 就会在容器中去找有没有 OrderDao类型对象
        4. 如果有,就会自动的装配, 老师提示如果是按照 byType 方式来装配, 这个容器中,不能有两个
          的OrderDao类型对象
        5. 如果你的对象没有属性,  autowire就没有必要写
        6. 其它类推..

        7. 如果我们设置的是 autowire="byName" 表示通过名字完成自动装配
        8. 比如下面的 autowire="byName" class="com.hspedu.spring.service.OrderService"
           1) 先看 OrderService 属性 private OrderDao orderDao
           2) 再根据这个属性的setXxx()方法的 xxx 来找对象id
           3) public void setOrderDao() 就会找id=orderDao对象来进行自动装配
           4) 如果没有就装配失败

    -->
    <bean autowire="byName" class="com.hspedu.spring.service.OrderService"
          id="orderService"/>

    <!--配置OrderAction-->
    <bean autowire="byName" class="com.hspedu.spring.web.OrderAction" id="orderAction"/>
    <!--指定属性文件
     老师说明
     1. 先把这个文件修改成提示All Problem
     2. 提示错误,将光标放在context 输入alt+enter 就会自动引入namespace
     3. location="classpath:my.properties" 表示指定属性文件的位置
     4. 提示,需要带上 classpath
     5. 属性文件有中文,需要将其转为unicode编码-> 使用工具
     -->
    <context:property-placeholder location="classpath:my.properties"/>
    <!--配置Monster对象
    1.通过属性文件给monster对象的属性赋值
    2. 这时我们的属性值通过${属性名}
    3. 这里说的 属性名 就是 my.properties文件中的 k=v 的k
    -->
    <bean class="com.hspedu.spring.bean.Monster" id="monster1000">
        <property name="monsterId" value="${monsterId}"/>
        <property name="skill" value="${skill}"/>
        <property name="name" value="${name}"/>
    </bean>

</beans>
package com.hspedu.spring.dao;

/**
 * @author 韩顺平
 * @version 1.0
 * DAO类
 */
public class OrderDao {
    //方法。。。
    public void saveOrder() {
        System.out.println("保存 一个订单...");
    }
}

package com.hspedu.spring.service;

import com.hspedu.spring.dao.OrderDao;

/**
 * @author 韩顺平
 * @version 1.0
 * Service类
 */
public class OrderService {
    //OrderDao属性
    private OrderDao orderDao;

    //getter
    public OrderDao getOrderDao() {
        return orderDao;
    }
    //setter
    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }
}

扫描

<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置容器要扫描的包
    老师解读
    1. component-scan 要对指定包下的类进行扫描, 并创建对象到容器
    2. base-package 指定要扫描的包
    3. 含义是当spring容器创建/初始化时,就会扫描com.hspedu.spring.component包
       下的所有的 有注解 @Controller / @Service / @Respository / @Component类
       将其实例化,生成对象,放入到ioc容器
    4. resource-pattern="User*.class" 表示只扫描com.hspedu.spring.component 和它的子包下的User打头的类

    -->
<!--    <context:component-scan base-package="com.hspedu.spring.component"/>-->


    <!--
        需求:如果我们希望排除某个包/子包下的某种类型的注解,可以通过exclude-filter来指定
        1. context:exclude-filter 指定要排除哪些类
        2. type 指定排除方式 annotation表示按照注解来排除
        3. expression="org.springframework.stereotype.Service" 指定要排除的注解的全路径
    -->

    <!--<context:component-scan base-package="com.hspedu.spring.component">-->
    <!--    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
    <!--    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>-->
    <!--</context:component-scan>-->

    <!--
        需求:如果我们希望按照自己的规则,来扫描包/子包下的某些注解, 可以通过 include-filter
        1. use-default-filters="false" 表示不使用默认的过滤机制/扫描机制
        2. context:include-filter 表示要去扫描哪些类
        3. type="annotation" 按照注解方式来扫描/过滤
        4. expression="org.springframework.stereotype.Service" 指定要扫描的注解的全路径
    -->

    <context:component-scan base-package="com.hspedu.spring.component" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

运用el表达式

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

    <!--配置一个monster对象-->
    <bean id="monster01" class="com.hspedu.spring.bean.Monster">
        <property name="monsterId" value="100"/>
        <property name="name" value="蜈蚣精~"/>
        <property name="skill" value="蜇人~"/>
    </bean>

    <!-- spring el 表达式使用
     老师解读
     1. 通过spel给bean的属性赋值
     -->
    <bean id="spELBean" class="com.hspedu.spring.bean.SpELBean">
        <!-- sp el 给字面量 -->
        <property name="name" value="#{'韩顺平教育'}"/>
        <!-- sp el 引用其它bean -->
        <property name="monster" value="#{monster01}"/>
        <!-- sp el 引用其它bean的属性值 -->
        <property name="monsterName" value="#{monster01.name}"/>
        <!-- sp el 调用普通方法(返回值)  赋值 -->
        <property name="crySound" value="#{spELBean.cry('喵喵的..')}"/>
        <!-- sp el 调用静态方法(返回值) 赋值 -->
        <property name="bookName" value="#{T(com.hspedu.spring.bean.SpELBean).read('天龙八部')}"/>
        <!-- sp el 通过运算赋值 -->
        <property name="result" value="#{89*1.2}"/>
    </bean>
</beans>
package com.hspedu.spring.bean;

/**
 * @author 韩顺平
 * @version 1.0
 */
public class SpELBean {

    private String name;
    private Monster monster;
    private String monsterName;
    private String crySound; //叫声
    private String bookName;
    private Double result;

    public SpELBean() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Monster getMonster() {
        return monster;
    }

    public void setMonster(Monster monster) {
        this.monster = monster;
    }

    public String getMonsterName() {
        return monsterName;
    }

    public void setMonsterName(String monsterName) {
        this.monsterName = monsterName;
    }

    public String getCrySound() {
        return crySound;
    }

    public void setCrySound(String crySound) {
        this.crySound = crySound;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public Double getResult() {
        return result;
    }

    public void setResult(Double result) {
        this.result = result;
    }

    //cry 方法会返回字符串
    public String cry(String sound) {
        return "发出 " + sound + "叫声...";
    }

    //read 返回字符串
    public static String read(String bookName) {
        return "正在看 " + bookName;
    }

    @Override
    public String toString() {
        return "SpELBean{" +
                "name='" + name + '\'' +
                ", monster=" + monster +
                ", monsterName='" + monsterName + '\'' +
                ", crySound='" + crySound + '\'' +
                ", bookName='" + bookName + '\'' +
                ", result=" + result +
                '}';
    }
}

注解配置

<?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 https://www.springframework.org/schema/context/spring-context.xsd">


    <context:component-scan
            base-package="com.hspedu.spring.component"/>

    <!--配置两个UserService对象-->
    <bean class="com.hspedu.spring.component.UserService" id="userService200"/>
    <bean class="com.hspedu.spring.component.UserService" id="userService300"/>
</beans>
package com.hspedu.spring.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

/**
 * @author 韩顺平
 * @version 1.0
 * @Controller 标识该类是一个控制器Controller, 通常这个类是一个Servlet
 */
@Controller
public class UserAction {
    //xml配置 ref
    //老师说明 @Autowired
    //1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean匹配(按照类型),则使用该bean装配
    //2)如待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值再进行查找,
    //  找到就装配,找不到就抛异常
    //@Autowired

    //老师说明 @Resource
    //1) @Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,
    //  而type属性则解析为bean的类型.所以如果使用name属性,则使用byName的自动注入策略,
    //  而使用type属性时则使用byType自动注入策略
    //  比如@Resource(name = "userService") 表示装配 id=userService对对象
    //  比如@Resource(type = UserService.class) 表示按照UserService.class类型进行装配, 这时要求容器中,只能有一个这样类型的对象
    //2) 如果@Resource 没有指定 name 和 type ,则先使用byName注入策略,
    //   如果匹配不上, 再使用byType策略, 如果都不成功,就会报错

    //=================================
    //老师说明: @Autowired + @Qualifier(value = "userService02") 组合也可以完成指定 name/id 来进行自动装配
    //指定id进行组装, 也可以使用@Autowired 和 @Qualifier(value = "userService02")
    // 这时,是装配的 id=userService02 , 需要两个注解都需要写上

    @Resource(name="userService")
    private UserService userService200;

    public void sayOk() {
        System.out.println("UserAction 的sayOk()");
        System.out.println("userAction 装配的 userService属性=" + userService200);
        userService200.hi();
    }
}

package com.hspedu.spring.component;

import org.springframework.stereotype.Service;

/**
 * @author 韩顺平
 * @version 1.0
 * @Service 标识该类是一个Service类/对象
 */
@Service
public class UserService {
    //方法..
    public void hi(){
        System.out.println("UserService hi()~");
    }
}

你可能感兴趣的:(spring,学习,java)