SSM-mybatis-spring容器 复杂和简化方法

回顾
-------------
    1、JVM
        runtime data area.
        a.method area
            方法区,永久区,metaspace , 共享
        b.heap
            堆区,共享
            heap    = young代 + old代理
            young    = 伊甸区 + 幸存区
            幸存区    = 幸存一区(from) + 幸存二区(to),内存碎片整理
            所有对象诞生于伊甸区。
            
            heap            //
            non-heap        //非堆 , metaspace
            off-heap        //离堆 , os - jvm
                            //ByteBuffer.allocateDirect(1024) ; cleaner
            -Xms            //堆初始值
            -Xmx            //堆最大值
            -Xmn            //年轻代大小
            -XX:NewSize
            -XX:MaxNewSize
            -XX:NewRatio        //年老代是年轻代的倍数
            -XX:SurvivorRatio    //伊甸区是单个幸存区的倍数
            -Xloggc:<file>        //
            
        c.java stack
            线程,StackFrame(method frame) , push | pop
            死递归 , 
            -Xss1m

        d.native method stack
        e.program couter register

        System.gc()
        没有任何指针能够直接或间接到达他。

        jvisualvm
        jconsole
        jmap


    2、ClassLoader
        类加载器,将类型映射到路径,加载对应字节码文件到内存的方法区。
        三级类加载机制,Bootstrap(核心类) -> ExtClassLoader(jreextxxx.jar) -> AppClassLoader
        extends ClassLoader{
            findClass(){
                defineClass(byte[] .. ) ;
            }
        }

    2、mybatis
        sql映射,oop方式访问jdbc。


实现mybatis的一对多关联关系
---------------------------
    1、修改Customer.class,增加集合属性
        class Customer{
            ...
            private List<Order> orders = new ArrayList<Order>();
            //get/set
        }
    2、修改CustomerMapper.xml
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="customers">
            <insert id="insert">
              insert into customers(name, age) values(#{name} , #{age})
            </insert>

            <update id="update">
                update customers set name = #{name} , age = #{age} where id = #{id}
            </update>

            <delete id="deleteOne">
                delete from customers where id = #{id}
            </delete>

            <delete id="deleteAll">
                delete from customers
            </delete>

            <select id="selectOne" resultMap="rmCustomer">
                SELECT
                  c.id cid ,
                  c.name cname ,
                  c.age cage ,
                  o.id oid ,
                  o.orderno oorderno,
                  o.price oprice,
                  o.cid ocid
                FROM
                  customes c left outer join orders o
                ON
                  c.id = o.cid
                WHERE
                  c.id = #{id}
            </select>
            <select id="selectAll" resultType="_Customer">
                select * from customers
            </select>
            
            <resultMap id="rmCustomer" type="_Customer">
                <id column="cid" property="id" />
                <result column="cname" property="name" />
                <result column="cage" property="age" />
                <collection property="orders" ofType="_Order" column="ocid">
                    <id column="oid" property="id" />
                    <result column="oorderno" property="orderNo" />
                    <result column="oprice" property="price"/>
                </collection>
            </resultMap>
        </mapper>
    3、测试
        @Test
        public void testSelectOne() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            Customer c = s.selectOne("customers.selectOne" , 6) ;
            s.commit();
            s.close();
        }
    4、


自关联
-----------------
    树形图 : 
    全国
       |---河北省
                 |---保定
                 |---张家口
       |---河南省
               |--驻马店
               |---开封

    1.设计表
        create table areas(id int primary key auto_increment , areaname varchar(20) , pid int) ;

    2.创建Area类
        public class Area {
            private Integer id ;
            private String areaName ;
            private Area parentArea ;
            //get/set
        }
    3.映射文件
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="areas">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into areas(areaname , pid) values(#{areaName} , #{parentArea.id})
            </insert>
        </mapper>
    
    4.配置文件
        <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
            <properties>
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/big10"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </properties>

            <!-- 定义类型别名 -->
            <typeAliases>
                <typeAlias type="com.oldboy.mybatis.domain.Customer" alias="_Customer" />
                <typeAlias type="com.oldboy.mybatis.domain.Order" alias="_Order" />
                <typeAlias type="com.oldboy.mybatis.domain.Area" alias="_Area" />
            </typeAliases>

            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${driver}"/>
                        <property name="url" value="${url}"/>
                        <property name="username" value="${username}"/>
                        <property name="password" value="${password}"/>
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="CustomerMapper.xml"/>
                <mapper resource="OrderMapper.xml"/>
                <mapper resource="AreaMapper.xml"/>
            </mappers>
        </configuration>

    5.插入
        @Test
        public void testInsert() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;

            Area a1 = new Area("quanguo") ;
            Area a2 = new Area("hebeisheng" , a1) ;
            Area a3 = new Area("henansheng", a1) ;
            Area a4 = new Area("baoding",a2) ;
            Area a5 = new Area("zhangjiakou", a2) ;
            Area a6 = new Area("zhumadian", a3) ;
            Area a7 = new Area("kaifeng", a3) ;
            s.insert("areas.insert" , a1);
            s.insert("areas.insert" , a2);
            s.insert("areas.insert" , a3);
            s.insert("areas.insert" , a4);
            s.insert("areas.insert" , a5);
            s.insert("areas.insert" , a6);
            s.insert("areas.insert" , a7);
            s.commit();
            s.close();
        }

实现自关联查询
------------------
    1.查询自己和上级的信息
        select 
            s.id sid,
            s.areaname sname ,
            p.id pid ,
            p.areaname pname
        from 
            areas s left outer join areas p on s.pid = p.id  ;

    2.编写AreaMapper.xml
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="areas">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into areas(areaname , pid) values(#{areaName} , #{parentArea.id})
            </insert>

            <select id="selectOne" resultMap="rmArea">
                select
                    s.id sid,
                    s.areaname sname ,
                    p.id pid ,
                    p.areaname pname
                from
                    areas s left outer join areas p on s.pid = p.id  
                WHERE
                    s.id = #{id}
            </select>
            <resultMap id="rmArea" type="_Area">
                <id column="sid" property="id" />
                <result column="sname" property="areaName" />
                <association property="parentArea" column="pid" javaType="_Area">
                    <id column="pid" property="id" />
                    <result column="pname" property="areaName"/>
                </association>
            </resultMap>
        </mapper>

    3.实现查询
        @Test
        public void testSelectOne() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            Area a1 = s.selectOne("areas.selectOne" , 2) ;

            s.commit();
            s.close();
        }

实现自关联的下级查询
----------------------
    1.增加Area的集合属性
        public class Area {
            ...
            //所辖区域集合
            private List<Area> children ;
            //get/set
        }
    2.映射文件
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="areas">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into areas(areaname , pid) values(#{areaName} , #{parentArea.id})
            </insert>

            <select id="selectOne" resultMap="rmArea">
                select
                    p.id pid,
                    p.areaname pname ,
                    s.id sid ,
                    s.areaname sname ,
                    c.id cid ,
                    c.areaname cname
                from
                    areas s
                    left outer join areas p on s.pid = p.id
                    left outer join areas c on c.pid = s.id
                where
                    s.id = #{id}
            </select>
            <select id="selectAll" resultMap="rmArea">
                select
                    p.id pid,
                    p.areaname pname ,
                    s.id sid ,
                    s.areaname sname ,
                    c.id cid ,
                    c.areaname cname
                from
                    areas s
                    left outer join areas p on s.pid = p.id
                    left outer join areas c on c.pid = s.id
            </select>
            <resultMap id="rmArea" type="_Area">
                <id column="sid" property="id" />
                <result column="sname" property="areaName" />
                <association property="parentArea" column="pid" javaType="_Area">
                    <id column="pid" property="id" />
                    <result column="pname" property="areaName"/>
                </association>
                <collection property="children" column="sid" ofType="_Area">
                    <id column="cid" property="id"/>
                    <result column="cname" property="areaName"/>
                </collection>
            </resultMap>
        </mapper>
    3.
        public void testSelectOne() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            Area a1 = s.selectOne("areas.selectOne" , 2) ;

            s.commit();
            s.close();
        }

        @Test
        public void testSelectAll() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            List<Area> list = s.selectList("areas.selectAll" ) ;

            s.commit();
            s.close();
        }

 一对一关系
 ---------------
    1.创建husband,wife表。
        [主键关联]
        原理是一张表的主键和另外外一张表相一致。
        create table husbands(id int primary key auto_increment , hname varchar(20)) ;
        create table wifes(id int primary key auto_increment , wname varchar(20)) ;
        
        [外键关联]
        原理等同于多对一关联关系。

    2.创建类
        //丈夫类
        public class Husband {
            private Integer id ;
            private String hname ;
            //一对一关联关系
            private Wife wife ;
        }

        //妻子类
        public class Wife {
            private Integer id ;
            private String wname ;

            //双向一对一关联
            private Husband husband ;
            ...
        }
    3.映射文件
        [丈夫]
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="husbands">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into husbands(hname) values(#{hname})
            </insert>

            <select id="selectOne" resultMap="rmHusband">
              select
                h.id hid ,
                h.hname hname ,
                w.wname wname
              FROM
                husbands h left outer join wifes w on h.id = w.id
              where
                h.id = #{id}
            </select>
            
            <resultMap id="rmHusband" type="_Husband">
                <id column="hid" property="id" />
                <result column="hname" property="hname" />
                <association property="wife" column="hid" javaType="_Wife">
                    <result column="wname" property="wname" />
                    <association property="husband" column="hid" javaType="_Husband">
                        <id column="hid" property="id"/>
                        <result column="hname" property="hname"/>
                    </association>
                </association>
            </resultMap>
        </mapper>

        [妻子]
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="wifes">
            <insert id="insert">
              insert into wifes(id , wname) values(#{husband.id} , #{wname})
            </insert>

        </mapper>
    4.配置文件
        <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
            <properties>
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/big10"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </properties>

            <!-- 定义类型别名 -->
            <typeAliases>
                <typeAlias type="com.oldboy.mybatis.domain.Customer" alias="_Customer" />
                <typeAlias type="com.oldboy.mybatis.domain.Order" alias="_Order" />
                <typeAlias type="com.oldboy.mybatis.domain.Area" alias="_Area" />
                <typeAlias type="com.oldboy.mybatis.domain.Husband" alias="_Husband" />
                <typeAlias type="com.oldboy.mybatis.domain.Wife" alias="_Wife" />
            </typeAliases>

            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${driver}"/>
                        <property name="url" value="${url}"/>
                        <property name="username" value="${username}"/>
                        <property name="password" value="${password}"/>
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="CustomerMapper.xml"/>
                <mapper resource="OrderMapper.xml"/>
                <mapper resource="AreaMapper.xml"/>
                <mapper resource="HusbandMapper.xml"/>
                <mapper resource="WifeMapper.xml"/>
            </mappers>
        </configuration>

    5.测试
        @Test
        public void testInsert() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            Husband h = new Husband();
            h.setHname("huangxiaoming");

            Wife w = new Wife();
            w.setHusband(h);
            w.setWname("ab");

            s.insert("husbands.insert" , h) ;
            s.insert("wifes.insert" , w) ;
            s.commit();
            s.close();
        }

        @Test
        public void testSelectOne() throws Exception {
            InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
            SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
            SqlSession s = f.openSession() ;
            Husband h = s.selectOne("husbands.selectOne",1);
            s.commit();
            s.close();
        }

多对多关系
-----------------
    1.创建表
        create table teas(id int primary key auto_increment , tno varchar(20)) ;
        create table stus(id int primary key auto_increment , sno varchar(20)) ;
        create table links(tid int , sid int) ;
    2.创建类
        [Tea]
        /**
         * 教师类
         */
        public class Tea {
            private Integer id ;
            private String tno ;

            private List<Stu> stus = new ArrayList<Stu>();

        }
        [Stu]
        /**
         * 学生类
         */
        public class Stu {
            private Integer id ;
            private String sno ;

            private List<Tea> teas = new ArrayList<Tea>();
        }

    3.映射文件
        [TeaMapper.xml]
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="teas">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into teas(tno) values(#{tno})
            </insert>
            <insert id="insertLinks">
              <foreach collection="stus" item="s">
                insert into links(tid,sid) values(#{id} , #{s.id});
              </foreach>
            </insert>

            <select id="selectOne" resultMap="rmTea">
                select
                    t.id tid ,
                    t.tno tno ,
                    s.id sid ,
                    s.sno sno
                from
                    teas t
                    left outer join links l on l.tid = t.id
                    left outer join stus s  on s.id = l.sid
                where
                    t.id = #{id}
            </select>
            <resultMap id="rmTea" type="_Tea">
                <id column="tid" property="id"/>
                <result column="tno" property="tno" />
                <collection property="stus" ofType="_Stu" column="tid">
                    <id column="sid" property="id" />
                    <result column="sno" property="sno" />
                </collection>
            </resultMap>
        </mapper>

        [StuMapper.xml]
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="stus">
            <insert id="insert" useGeneratedKeys="true" keyProperty="id">
              insert into stus(sno) values(#{sno})
            </insert>
        </mapper>
    4.修改配置文件,添加执行多条语句支持
        <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
            <properties>
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/big10?allowMultiQueries=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </properties>

            <!-- 定义类型别名 -->
            <typeAliases>
                <typeAlias type="com.oldboy.mybatis.domain.Customer" alias="_Customer" />
                <typeAlias type="com.oldboy.mybatis.domain.Order" alias="_Order" />
                <typeAlias type="com.oldboy.mybatis.domain.Area" alias="_Area" />
                <typeAlias type="com.oldboy.mybatis.domain.Husband" alias="_Husband" />
                <typeAlias type="com.oldboy.mybatis.domain.Wife" alias="_Wife" />
                <typeAlias type="com.oldboy.mybatis.domain.Tea" alias="_Tea" />
                <typeAlias type="com.oldboy.mybatis.domain.Stu" alias="_Stu" />
            </typeAliases>

            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${driver}"/>
                        <property name="url" value="${url}"/>
                        <property name="username" value="${username}"/>
                        <property name="password" value="${password}"/>
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="CustomerMapper.xml"/>
                <mapper resource="OrderMapper.xml"/>
                <mapper resource="AreaMapper.xml"/>
                <mapper resource="HusbandMapper.xml"/>
                <mapper resource="WifeMapper.xml"/>
                <mapper resource="TeaMapper.xml"/>
                <mapper resource="StuMapper.xml"/>
            </mappers>
        </configuration>

    5.测试类
        package com.oldboy.mybatis.test;

        import com.oldboy.mybatis.domain.Husband;
        import com.oldboy.mybatis.domain.Stu;
        import com.oldboy.mybatis.domain.Tea;
        import com.oldboy.mybatis.domain.Wife;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSession;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        import org.junit.Test;

        import java.io.InputStream;

        /**
         * 测试多对多
         */
        public class TestMany2Many {
            @Test
            public void testInsert() throws Exception {
                InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
                SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
                SqlSession s = f.openSession() ;

                Stu s1 = new Stu("s1") ;
                Stu s2 = new Stu("s2") ;
                Stu s3 = new Stu("s3") ;
                Stu s4 = new Stu("s4") ;

                Tea t1 = new Tea("t1");
                Tea t2 = new Tea("t2");

                t1.addStus(s1 ,s2 , s3);
                t2.addStus(s2 , s3 , s4);

                s.insert("stus.insert" , s1);
                s.insert("stus.insert" , s2);
                s.insert("stus.insert" , s3);
                s.insert("stus.insert" , s4);

                s.insert("teas.insert" , t1);
                s.insert("teas.insert" , t2);

                s.insert("teas.insertLinks" , t1);
                s.insert("teas.insertLinks" , t2);

                s.commit();
                s.close();
            }

            @Test
            public void testSelectOne() throws Exception {
                InputStream in = Resources.getResourceAsStream("mybatis-conf.xml") ;
                SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in) ;
                SqlSession s = f.openSession() ;
                Tea t = s.selectOne("teas.selectOne" , 3) ;
                s.commit();
                s.close();
            }
        }

聚合函数查询
-----------------
    1.Mapper.xml
        <select id="selectCount" resultType="int">
            select count(*) from teas
        </select>
    2.查询
        int cnt = s.selectOne("teas.selectCount") ;
    
    3.多个聚合
        <select id="selectAgg" resultType="map">
            select max(price) max , min(price) min , avg(price) avg from orders
        </select>
    
    4.查询
        Map map = s.selectOne("orders.selectAgg");

    5.查询没有学生的老师数量
        1.查询不在links中出现的tid的数量。
            select count(distinct id) from teas where id not in (select distinct tid from links) ;
        
        2.连接查询
            select count(*) from teas t left outer join links l on l.tid = t.id where l.sid is null; 


Spring
-----------------
    业务层框架,管理bean,容器。 
    体验spring
    1、创建模块,添加maven依赖。 
        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>

            <groupId>com.oldboy</groupId>
            <artifactId>myspring</artifactId>
            <version>1.0-SNAPSHOT</version>
            <dependencies>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.11</version>
                </dependency>
                <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                    <version>4.3.5.RELEASE</version>
                </dependency>
            </dependencies>
        </project>
        
    2、创建接口和实现类
        [WelcomeService]
        public interface WelcomeService {
            public void sayHello() ;
        }

        [WelcomeServiceImpl]
        package com.oldboy.myspring.service;

        /**
         * 实现类
         */
        public class WelcomeServiceImpl implements WelcomeService{
            private String name ;

            public String getName() {
                return name;
            }

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

            public void sayHello() {
                System.out.println(name);
            }
        }

        [ByeService]
        public interface ByeService {
            public void sayBye();
        }

        [ByeServiceImpl]
        package com.oldboy.myspring.service;

        /**
         * Created by Administrator on 2018/4/28.
         */
        public class ByeServiceImpl implements ByeService{
            private String bye ;

            public String getBye() {
                return bye;
            }

            public void setBye(String bye) {
                this.bye = bye;
            }

            public void sayBye() {
                System.out.println(bye);
            }
        }



    3、创建配置文件
        [resource/beans.xml]
        <?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">
            <!-- 配置bean -->
            <bean id="welService" class="com.oldboy.myspring.service.WelcomeServiceImpl">
                <property name="name" value="hello world" />
                <property name="bs" ref="byeService" />
            </bean>
            <!-- byeService -->
            <bean id="byeService" class="com.oldboy.myspring.service.ByeServiceImpl">
                <property name="bye" value="bye bye!!!" />
            </bean>
        </beans>

    4、App.java
        package com.oldboy.myspring;

        import com.oldboy.myspring.service.ByeService;
        import com.oldboy.myspring.service.WelcomeService;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

        /**
         */
        public class App {
            public static void main(String[] args) {
                //创建spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                //从容器提取指定bean
                WelcomeService ws = (WelcomeService) ac.getBean("welService");
                ws.sayHello();

                //
                ByeService bs = (ByeService) ac.getBean("byeService");
                bs.sayBye();
            }
        }

spring
----------------
    思想两个:ioc和aop
    ioc : inverse of control,反转控制,获得对象的方式反转了。
    aop : aspect oriented program,面向方面编程。

    bean的范围:
    1.singleton
        单例,默认值。
    2.prototype
        原型,每次get都是创建新对象,等价于new操作。


    aop
    --------------
        系统级功能,aop对oop的增强。proxy
        1.引入新依赖
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.10</version>
            </dependency>
            
        2.创建目录类和接口
            略
        3.创建前置通知
            public class MyMethodBeforeAdvice implements MethodBeforeAdvice{
                public void before(Method method, Object[] args, Object target) throws Throwable {
                    System.out.println("hello world");
                }
            }

        4.配置文件
            <?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">
                <!-- 前置通知 -->
                <bean id="beforeAdvice" class="com.oldboy.myspring.aop.MyMethodBeforeAdvice" />

                <!-- 目标对象 -->
                <bean id="welserviceTarget" class="com.oldboy.myspring.aop.WelcomeServiceImpl">
                    <property name="name" value="tom" />
                </bean>

                <bean id="welService" class="org.springframework.aop.framework.ProxyFactoryBean">
                    <!--  代理接口集-->
                    <property name="proxyInterfaces">
                        <list>
                            <value>com.oldboy.myspring.aop.WelcomeService</value>
                        </list>
                    </property>
                    <!-- 拦截器名集 -->
                    <property name="interceptorNames">
                        <list>
                            <value>beforeAdvice</value>
                        </list>
                    </property>
                    <property name="target" ref="welserviceTarget" />
                </bean>
            </beans>
        5.测试
            package com.oldboy.myspring.aop;

            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;

            /**
             */
            public class App {
                public static void main(String[] args) {
                    //创建spring容器
                    ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml");
                    WelcomeService ws = (WelcomeService) ac.getBean("welcomeService");
                    ws.sayHello();
                }
            }


后置通知
----------------
    1.创建通知
        /**
         * 后置通知
         */
        public class MyAfterReturningAdvice implements AfterReturningAdvice {
            public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
                System.out.println("after");
            }
        }
    
    2.配置aop.xml
        <?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">
            <!-- 前置通知 -->
            <bean id="beforeAdvice" class="com.oldboy.myspring.aop.MyMethodBeforeAdvice" />
            <bean id="afterAdvice" class="com.oldboy.myspring.aop.MyAfterReturningAdvice" />

            <!-- 目标对象 -->
            <bean id="welserviceTarget" class="com.oldboy.myspring.aop.WelcomeServiceImpl">
                <property name="name" value="tom" />
            </bean>

            <!-- 代理对象 -->
            <bean id="welcomeService" class="org.springframework.aop.framework.ProxyFactoryBean">
                <!--  代理接口集-->
                <property name="proxyInterfaces">
                    <list>
                        <value>com.oldboy.myspring.aop.WelcomeService</value>
                    </list>
                </property>
                <!-- 拦截器名集 -->
                <property name="interceptorNames">
                    <list>
                        <value>beforeAdvice</value>
                        <value>afterAdvice</value>
                    </list>
                </property>
                <property name="target" ref="welserviceTarget" />
            </bean>
        </beans>
    
    3.测试
        略


环绕通知
------------------
    1.创建通知
        package com.oldboy.myspring.aop;

        import org.aopalliance.intercept.MethodInterceptor;
        import org.aopalliance.intercept.MethodInvocation;

        /**
         * 环绕通知
         */
        public class MyMethodInterceptor implements MethodInterceptor {
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("begin");
                //调用目标对象的方法
                Object ret = invocation.proceed() ;
                System.out.println("end");
                return ret;
            }
        }

    2.aop.xml
        <?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">
            <!-- 前置通知 -->
            <bean id="beforeAdvice" class="com.oldboy.myspring.aop.MyMethodBeforeAdvice" />
            <!-- 后置通知 -->
            <bean id="afterAdvice" class="com.oldboy.myspring.aop.MyAfterReturningAdvice" />
            <!-- 环绕通知 -->
            <bean id="roundAdvice" class="com.oldboy.myspring.aop.MyMethodInterceptor" />

            <!-- 目标对象 -->
            <bean id="welserviceTarget" class="com.oldboy.myspring.aop.WelcomeServiceImpl">
                <property name="name" value="tom" />
            </bean>

            <!-- 代理对象 -->
            <bean id="welcomeService" class="org.springframework.aop.framework.ProxyFactoryBean">
                <!--  代理接口集-->
                <property name="proxyInterfaces">
                    <list>
                        <value>com.oldboy.myspring.aop.WelcomeService</value>
                    </list>
                </property>
                <!-- 拦截器名集 -->
                <property name="interceptorNames">
                    <list>
                        <value>beforeAdvice</value>
                        <value>afterAdvice</value>
                        <value>roundAdvice</value>
                    </list>
                </property>
                <property name="target" ref="welserviceTarget" />
            </bean>
        </beans>
    3.测试
        略

异常通知
-----------------
    1.创建通知
        package com.oldboy.myspring.aop;

        import org.springframework.aop.ThrowsAdvice;

        import java.lang.reflect.Method;

        /**
         * 异常通知
         */
        public class MyThrowAdvice implements ThrowsAdvice{
            public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
                System.out.println("出事了!!");
                ex.printStackTrace();
            }
        }

    2.aop.xml
        <?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">
            <!-- 前置通知 -->
            <bean id="beforeAdvice" class="com.oldboy.myspring.aop.MyMethodBeforeAdvice" />
            <!-- 后置通知 -->
            <bean id="afterAdvice" class="com.oldboy.myspring.aop.MyAfterReturningAdvice" />
            <!-- 环绕通知 -->
            <bean id="roundAdvice" class="com.oldboy.myspring.aop.MyMethodInterceptor" />
            <!-- 异常通知 -->
            <bean id="throwsAdvice" class="com.oldboy.myspring.aop.MyThrowAdvice" />

            <!-- 目标对象 -->
            <bean id="welserviceTarget" class="com.oldboy.myspring.aop.WelcomeServiceImpl">
                <property name="name" value="tom" />
            </bean>

            <!-- 代理对象 -->
            <bean id="welcomeService" class="org.springframework.aop.framework.ProxyFactoryBean">
                <!--  代理接口集-->
                <property name="proxyInterfaces">
                    <list>
                        <value>com.oldboy.myspring.aop.WelcomeService</value>
                    </list>
                </property>
                <!-- 拦截器名集 -->
                <property name="interceptorNames">
                    <list>
                        <value>beforeAdvice</value>
                        <value>afterAdvice</value>
                        <value>roundAdvice</value>
                        <value>throwsAdvice</value>
                    </list>
                </property>
                <property name="target" ref="welserviceTarget" />
            </bean>
        </beans>
    3.测试
        略


观众和演员的关系
-------------------
    1.观众类
        public class Audience {
            public void turnOffCellphone(){
                System.out.println("turnOffCellphone");
            }

            public void sitdown(){
                System.out.println("sitdown");
            }
            
            public void applaud(){
                System.out.println("applaud");
            }
            
            public void payOff(){
                System.out.println("payoff");
            }
            
            public void gohome(){
                System.out.println("gohome");
            }
        }

    2.创建演员类和接口
        [Performer]
        package com.oldboy.myspring.aop2;

        /**
         * Created by Administrator on 2018/4/28.
         */
        public interface Performer {
            public void show();
        }

        [Singer]
        package com.oldboy.myspring.aop2;

        /**
         * 歌手演员
         */
        public class Singer implements Performer{
            public void show() {
                System.out.println("啦啦啦~~~");
            }
        }

    3.aop.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:aop="http://www.springframework.org/schema/aop"
               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
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

            <!-- 观众 -->
            <bean id="audience" class="com.oldboy.myspring.aop2.Audience"/>

            <!-- 歌手 -->
            <bean id="singer" class="com.oldboy.myspring.aop2.Singer"/>


            <aop:config>
                <!-- 将观众配置成方面 -->
                <aop:aspect id="audienceAspect" ref="audience">
                    <aop:pointcut id="audiencePointcut" expression="execution(* *..Performer.*(..))" />
                    <aop:before method="turnOffCellphone" pointcut-ref="audiencePointcut" />
                    <aop:before method="sitdown" pointcut-ref="audiencePointcut"/>
                    <aop:after-returning method="applaud" pointcut-ref="audiencePointcut"/>
                    <aop:after-throwing method="payOff" pointcut-ref="audiencePointcut"/>
                    <aop:after method="gohome" pointcut-ref="audiencePointcut"/>
                </aop:aspect>
            </aop:config>
        </beans>


使用环绕通知实现aop
---------------------
    1.观众类
        package com.oldboy.myspring.aop3;

        import org.aspectj.lang.ProceedingJoinPoint;

        /**
         * 观众bean
         */
        public class Audience {

            //环绕通知了.
            public Object watch(ProceedingJoinPoint pjp){
                try {
                    System.out.println("turnoffCellphone");

                    System.out.println("sitDown");
                    //开始你的表演
                    Object ret = pjp.proceed();
                    System.out.println("applaud");
                    return ret ;
                }
                catch (Throwable e) {
                    System.out.println("payOff");
                    e.printStackTrace();
                }
                finally {
                    System.out.println("gohome");
                }
                return null ;
            }
        }

    2.aop3.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:aop="http://www.springframework.org/schema/aop"
               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
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

            <!-- 观众 -->
            <bean id="audience" class="com.oldboy.myspring.aop3.Audience"/>

            <!-- 歌手 -->
            <bean id="singer" class="com.oldboy.myspring.aop3.Singer"/>


            <aop:config>
                <!-- 将观众配置成方面 -->
                <aop:aspect id="audienceAspect" ref="audience">
                    <aop:around method="watch" pointcut="execution(* *..Performer.*(..))" />
                </aop:aspect>
            </aop:config>
        </beans>
    
    3.测试
        package com.oldboy.myspring.aop3;

        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

        /**
         */
        public class App {
            public static void main(String[] args) {
                //创建spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");
                Performer p = (Performer) ac.getBean("singer");
                p.show();
            }
        }

bean的简化配置
---------------------
    1.简介
        如果配置大量的bean,繁琐。

    2.在配置的类上增加注解。
        @Service            //服务
        @Controller            //控制器
        @Component            //组件
        @Repository            //仓库

        @Service("ws")
        @Scope("prototype")
        public class WelcomeServiceImpl implements WelcomeService{
            ...

            @Resource(name="byeService")
            private ByeService bs ;
        }


    3.配置文件beans2.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:aop="http://www.springframework.org/schema/aop"
               xmlns:context="http://www.springframework.org/schema/context"
               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
                                http://www.springframework.org/schema/context
                                http://www.springframework.org/schema/context/spring-context-4.3.xsd
                                http://www.springframework.org/schema/aop
                                http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
            <!-- 组件扫描 -->
            <context:component-scan base-package="com.oldboy.myspring.service" />
        </beans>
        
    4.测试
        //创建spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans2.xml");
        WelcomeService ws = (WelcomeService) ac.getBean("welcomerService");
        ws.sayHello();
原文地址:https://www.cnblogs.com/zyde/p/8969273.html