spring框架总结

---恢复内容开始---

spring框架主要核心的部分分为两个部分:

        aop:面向切面编程 不通过修改源代码,对功能进行扩张增强

     ioc:控制反转      通常我们建立对象都是通过new的形式进行创建对象,但是我们这里是通过交给spring来进行创建对象

  什么是spring?

        spring为一个开源轻量级框架   他是一个一站式框架  对javeee的3层结构都提供了不同的技术 

  有什么用?

        具体的用法分为ioc与aop两个方面

       ioc的底层原理:

             配置xml文件

           dom4J进行解析

               得到class路径也就是名称

              通过Class类的newinstance方法创建对象

          spring的bean管理(配置xml文件方式)

                  bean的实例化有3个方面

                        1.通过无参构造函数进行

                        2.通过静态工厂来进行创建

                                   

1
<bean id="factory" class="com.jdztc.ioc.Factory" factory-method="getUser"></bean>

  getUser为com.jdztc.ioc.Factory类中的静态方法得到对象

                          3.通过实例工厂来进行创建(就是创建对象的方法不是静态方法)

    首先需要进行对对象的创建否则将不能轻松的调用getUser方法

1
2
<bean id="factoryshili" class="com.jdztc.bean.FactoryShiLi" ></bean>
        <bean id="bean2" factory-bean="factoryshili" factory-method="getUser"></bean><br>

  

scope属性的介绍:

         他为bean的作用范围

             默认值为singleton  为单实例对象

             prototype:为多实例对象

             request:创建对象把对象放入request中

             session:创建对象把对象放入sesison中

             gobleSession:创建对象把对象放入session中    具体应用:百度首页登录一次其他应用都可以使用

属性注入介绍:

          向对象中的属性注入值

          有3种方式:1.set方法进行注入(用的最多)

1
<bean id="user1" class="com.jdztc.type.User"><property name="username" value="你好"></property></bean>

 

                         <property></property>

                           2.有参构造函数

 

1
2
3
4
<!-- 属性注入(构造方法) -->
        <bean id="user2" class="com.jdztc.type.UserConstructor">
               <constructor-arg name="username" value="你好"></constructor-arg>
        </bean>

 

                              <constructor-arg>标签

                           3接口注入方式(不支持) 

              注入复杂类型属性:

                  注入对象类型属性:(用的最多)

                             

1
2
3
4
5
<!-- 注入对象类型属性 -->
       <bean id="dao" class="com.jdztc.type.UserDao"></bean>
       <bean id="service" class="com.jdztc.type.UserService">
           <property name="userDao" ref="dao"/>
       </bean>

                      P名称空间注入(一个标签不能多个相同的属性)

               

1
2
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.jdztc.type.Person" p:pname="你不好">

                 注入arr数组  list集合   map集合   properties集合

                   arr数组的注入方式很相似

                        <list><value></value><l/ist>形式有多少个值就有多少个value

                    map集合

                         <map><entry key="" vlaue=""></entry></map>

                   properties

                           <props><prop key="">你好</prop></props>

                           ioc与dI的区别

                                    ioc:对象的创建交给spring来创建

                                    DI:依赖注入    给对象中的属性注入值

                                    DI不能单独存在  ,他是建立在ioc的基础之上的

                           spring整合项目原理

                          核心配置文件的加载和对象的创建交给服务器来创建,也就是在服务器加载的时候创建

                          用到的ServletContext和监听器

                              在web.xml文件中配置   

1
2
3
4
<!--配置监听器 -->
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

 

  

1
2
3
4
5
<!--指定spring配置文件  -->
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring2.xml</param-value>
    </context-param>

                     原理:使用监听器听到ServletContext创建时,进行了以下操作

                                1:加载核心配置文件,创建配置文件的对象

                                2.把配置文件的对象放入servletContext中  setAttribute()方法

                                 3.获取配置文件对象    getAttribute()

       spring的bean管理方式(注解方式实现)

                         导入aopjar包

                          开启注解扫描

                        对类.方法.属性都进行扫描

                          <context:component-scan>

                         只对类的属性

                          <context:annotation-config>

                          注解创建对象

                             @component(value="对象名")

                             @controller(value="")  web层

                             @service                 service层            功能是一致的都能创建对象

                             @Repository            持久层

                @scope配置范围   是单实例还是多实例对象

                            注解注入属性

                                     @AutoWired  不需要set方法和类的注解的value值无关   主要是根据属性来找

                                    @Resource   value值要与类的注解的vlaue保持一致

      aop方面:

                                        

                           原理:1.不修改原代码进行对功能的扩展2.采用横向抽取机制 

                     横向抽取机制与纵向抽取机制

                    纵向抽取:

                 

1
2
3
4
5
6
7
8
9
10
public  class Fu{
      publci void add(){
}
}
public Class Zi extends Fu{
       public void add(){
        super.add()
}
             
}

       横向抽取机制

      底层使用动态代理实现

              动态代理分为:

               jdk动态代理针对有接口的情况

               原理:创建接口实现类的代理对象(实现InvocationHandler接口),这个对象有着与实现类相同的功能

             

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.jdztc.aop;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
 * 针对有接口的情况,使用jdk的动态代理
 * @author 付鹏鹏
 *
 */
interface Fuu{
    public void add();
}
public class ZhongXiangChouQuDemo implements Fuu{
 
    //要增强的方法即切入点
    @Override
    public void add() {
        // TODO Auto-generated method stub
        //实现快速的拉屎   增强拉屎的功能
        System.out.println("拉屎");      
    }
 
}
/**
 * 创建与实现类相同功能的代理类
 * @author 付鹏鹏
 *
 */
class FuuProxy implements InvocationHandler{
 
    private ZhongXiangChouQuDemo zhongxiang;
    /**
     * 覆盖其默认构造函数
     */
    public FuuProxy(ZhongXiangChouQuDemo zhongxiang) {
        this.zhongxiang = zhongxiang;
    }
    /**
     * 生成实现类相同功能的代理对象
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(zhongxiang.getClass().getClassLoader(), zhongxiang.getClass().getInterfaces(), this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        Object result=null;
        System.out.println("事物的开启");
        result=method.invoke(zhongxiang, args);
        System.out.println("事物的结束");
        return result;
    }
     
     
}

  具体的调用    

1
2
3
4
5
//创建jdk动态代理类
        /*ZhongXiangChouQuDemo zhongxiang=new ZhongXiangChouQuDemo();
        FuuProxy proxy=new FuuProxy(zhongxiang);
        Fuu fuu=(Fuu) proxy.getProxy();
        fuu.add();*/

         cglib动态代理  针对没有接口的情况下

              原理:创建子类代理对象与子类有着相同的功能(实现methodInterceptor)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.jdztc.aop;
 
import java.lang.reflect.Method;
 
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
 
import javassist.util.proxy.MethodHandler;
 
/**
 * 没有接口的情况下  使用cglib动态代理
 * @author 付鹏鹏
 *
 */
class Dao{
    public void add(){
        System.out.println("拉屎");
    }
}
public class CglibProxyDemo extends Dao{
    public void add(){
        System.out.println("拉屎");
    }
}
/**
 * 创建子类的代理对象
 * @author 付鹏鹏
 *
 */
class CglibProxy implements MethodInterceptor{
    private Object terget;
    public CglibProxy(Object terget) {
        this.terget = terget;
    }
    public Object getIntercept(){
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(terget.getClass());
        //回调方法
        enhancer.setCallback(this);
        //创建对象
        return enhancer.create();
    }
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("食物开启前");
        arg3.invoke(terget, arg2);
        System.out.println("事务结束了");
        return null;
    }
     
}

  

               具体的调用

         

1
2
3
4
Dao cglibProxyDemo=new Dao();
        CglibProxy cglibProxy=new CglibProxy(cglibProxyDemo);
        Dao Dao=(Dao) cglibProxy.getIntercept();
        Dao.add();

   上面两种方式都对方法进行了增强

       aop术语:

         切入点:真正被增强的方法

         增强或通知:你要实现增强的逻辑

              前置增强:在方法执行之前

              后置增强:在方法执行之后

              异常增强:在方法出现异常时执行

              最终通知:在后置之后执行

              环绕执行:在方法之前执行    方法之后执行也会执行

         切面:将增强具体应用到切入点中的过程

         这3个为常用的术语

            连接点:类里面有哪些可以被增强,这些方法就是连接点

           引介:动态的添加方法和属性

           target(目标对象):代理目标(要增强的类)

           wearing(织入):把增强应用到目标对象的过程

           proxy(代理):一个类被aop织入增强后,就产生一个结果代理类

            

      aop操作

    

                基于aspectj的aop操作

                     aspectj是什么?他是面向切面的框架(把动态代理那些功能进行了封装)

               实现方式:

                       1.基于aspectj的xml配置

                       2.基于aspectj的注解

                       引入约束

                          导入jar包spring-aop       spring-aspectj   aopaliance    aspectj-weaver

                       使用表达式配置切入点

                             execution(* cn.itcase.aop.book.add(..))表示配置add切入点

                             execution(* cn.itcase.aop.Book.*(..))表示配置book类中所有的切入点

                            execution(* save*(..))匹配所有以save开头的方法

                       具体的应用

                       首先要创建对象

                    

1
2
3
<!--创建两个类的对象  -->
       <bean id="book" class="com.jdztc.aspectj.Book"></bean>
       <bean id="mybook" class="com.jdztc.aspectj.MyBook"></bean>

  

                       aop配置

                      配置切入点

                       将增强应用到切入点中

1
2
3
4
5
6
7
8
9
10
11
<!--aop配置  -->
       <aop:config>
       <!--*后要有空格  -->
       <!-- 配置切入点 -->
              <aop:pointcut expression="execution(* com.jdztc.aspectj.Book.*(..))" id="pointcut1"/>
        <!-- 配置切面   把增强应用到方法当中的过程-->
              <aop:aspect ref="mybook">
                    <aop:before method="before1" pointcut-ref="pointcut1"/>
                    <aop:around method="around" pointcut-ref="pointcut1"/>
              </aop:aspect>
       </aop:config>

  

1
2
3
4
5
6
7
8
package com.jdztc.dao;
 
public class Book {
 
    public void add(){
        System.out.println("add....");
    }
}

      

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.jdztc.aspectj;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public class MyBook {
 
    public void before1(){
        System.out.println("before前置增强...");
    }
    /**
     * 环绕增强
     * @throws Throwable
     */
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("方法之前");
        //执行方法
        proceedingJoinPoint.proceed();
        System.out.println("方法之后");
    }
}

  log4j介绍:

              info  只能看到基本信息

             debug  可以看到详细的信息

     基于aspectj的注解aop操作

        1创建对象 2开启aop操作   在增强类中使用   在类的上面使用@Aspectj     在方法的上面使用@Before

         具体的例子

              

1
2
3
4
5
<bean id="book" class="com.jdztc.dao.Book"></bean>
       <!--增强类-->
       <bean id="mybook" class="com.jdztc.service.MyBook"></bean>
       <!--开启aop注解操作 -->
       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

  

1
2
3
4
5
6
7
8
9
10
11
12
package com.jdztc.service;
 
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class MyBook {<br>       //value值为切入点
    @Before(value = "execution(* com.jdztc.dao.Book.*(..))")
    public void before1(){
        System.out.println("before1.....");
    }
}<br>

    JDBCTemplate操作和使用

                他与dbutil的使用很相似

                   dbutil操作实现查询要实现ResultSetHanlder

                 QueryRunner runner=new QueryRunner(dataSource);

               查询对象

                 runner.query(sql,new BeanHanlder<User>(User.calss))

                 BeanHanlder为ResuleSetHanlder接口的实现类

 

                 runner.query(sql,new ResultlistHanlder<User>(User.class))

                 ResultListHanlder为ResultSetHanlder接口的实现类

              JdbcTemplate实现查询也实现了接口RowMapper

                     具体的代码:

                  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package com.jdztc.jdbctemplate;
 
 
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
 
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
 
 
 
 
 
public class JdbcTemplateQuery {
 
    /**
     * jdbc模版查询返回list  使用query方法
     *
     */
    @Test
    public void queryList(){
        //创建对象
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        //设置数据库连接条件
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        //创建jdbc模版对象
        JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
        String sql="select * from spring_03";
        //调用模版的查询的方法queryForObject方法    
        List<User> list=jdbcTemplate.query(sql,new MyRowMapper());
        System.out.println(list);
         
         
         
    }
    /**
     * jdbc模版查询返回对象
     *
     */
    @Test
    public void queryObject(){
        //创建对象
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        //设置数据库连接条件
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        //创建jdbc模版对象
        JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
        String sql="select * from spring_03 where id=?";
        //调用模版的查询的方法queryForObject方法    
        User user=jdbcTemplate.queryForObject(sql, new MyRowMapper(), 1);
        System.out.println(user);
         
    }
    /**
     * 查询有多少条记录
     * 查询返回某一个值  使用queryForObject方法  他的第二个参数 为返回值类型的字节码文件
     */
    @Test
    public void testCount(){
        //创建对象
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        //设置数据库连接条件
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        //创建jdbc模版对象
        JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
        String sql="select count(*) from spring_03";
        //调用模版的查询的方法queryForObject方法    
        int a=jdbcTemplate.queryForObject(sql,Integer.class);
        System.out.println(a);
         
    }
    /**
     * jdbc的底层代码
     */
    @Test
    public void query(){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet rs=null;
        //加载驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //建立连接
            String url="jdbc:mysql://localhost:3306/spring";
            String user="root";
            String password="";
            connection=DriverManager.getConnection(url, user, password);
            String sql="select * from spring_03 where id=?";
            //预编译sql语句
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setInt(1,1);;
            rs=preparedStatement.executeQuery();
            while(rs.next()){
                //System.out.println(rs.next());
                User user1=new User();
                String username=rs.getString("username");
                String password1=rs.getString("password");
                user1.setPassword(password1);
                user1.setUsername(username);
                System.out.println(user1);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if (connection != null) {
                    connection.close();
                }
                if (rs != null) {
                    rs.close();
                }
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             
        }
    }
}
class MyRowMapper implements RowMapper<User>{
 
    @Override
    public User mapRow(ResultSet rs, int arg1) throws SQLException {
        // TODO Auto-generated method stub
        //不需要遍历结果集 这个已在JdbcTemplate中实现了
        User user=new User();
        String username = rs.getString("username");
        String password = rs.getString("password");
        user.setPassword(password);
        user.setUsername(username);
     
        return user;
    }
     
}

  

               c3p0连接池

                    记住这个ComboPooledDataSource对象

                    spring的事务的介绍

                     什么是事务?

                         事务是操作数据库的基本单位    指的是一组操作  这组操作要么都成功要么都失败

                    事务的特性

                         原子性:一组操作要么都成功要么都失败

                        一致型:操作之前之后保持一致

                        隔离性:多个事务操作一个数据,不影响

                        持久性:在数据生效后一直是那样

                    不考虑隔离性产生读问题

                       脏读   不可重复读   还有虚读

                    解决读问题:

                     设置隔离级别

                   事务管理器

                    对象platformTransactionManager

                    spring为不同的持久化技术提供了不同的接口实现

                      jdbcTemplate  和myBatis     DataSourceTransactionManager

                      hibernate5.0  hibernateTranactionManager

                     如何配置事务

                           编程式事务管理(基本不用)

                          声明式事务管理 :

                               1  基于xml配置文件形式实现

                               2   注解方式实现

                       配置步骤:

                            1.配置事务管理器

                            2.配置事务增强

                            3.配置切面(aop操作)

 

                       

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 配置事务管理器 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 配置DataSource属性  与连接池对应 -->
                <property name="dataSource" ref="dataSource"></property>
       </bean>
        
       <!-- 事物增强   根据事物管理器进行事务的增强 -->
       <tx:advice id="aaa" transaction-manager="transactionManager">
           <tx:attributes>
                    <!-- 设置事务操作的方法匹配规则    propagation="REQUIRED"设置事务隔离级别  -->
                    <tx:method name="account*"/>
           </tx:attributes>
       </tx:advice>
       <!-- 配置切面 -->
       <aop:config>
            <!--配置切入点  -->
            <aop:pointcut expression="execution(* com.jdztc.service.OrderService.account(..))" id="pointcut1"/>
            <!-- 将增强应用到切入点中 -->
            <aop:advisor advice-ref="aaa" pointcut-ref="pointcut1"/>
       </aop:config>

       注解方式实现

            

1
2
3
4
5
6
7
<!-- 配置事务管理器 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 配置DataSource属性  与连接池对应 -->
                <property name="dataSource" ref="dataSource"></property>
       </bean>
       <!-- 开启注解事物 -->
       <tx:annotation-driven transaction-manager="transactionManager"/>

  在你要配置事务的类的上方加上@Transactional  对类中的所有方法加上事务

  

  ssh框架整合思想:

       两个两个进行整合

       struts2对spring框架进行整合

           action对象交给spring进行管理

      spring对hibernate进行整合

          将数据库交给spring进行管理  写到spring的配置文件当中

         创建sessionFactory 交给spring进行配置

     

         

          

 

    

     

       

---恢复内容结束---

posted @   0101无限的空间  阅读(182)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示