• 18-spring


    目录:

    jar包下载:

    http://repo.spring.io/libs-release-local/org/springframework/spring/

    基础jar包:5+1

    • spring:

    • 第三方日志jar包:
      • 下载:百度搜索commons-logging.jar mvn,点击第一个链接

                          

      •  要这个

                                   

      • 下载jar文件:

                                    

                     


    第一个spring程序示例

    1. 导入jar包
    2. 配置applicationContext.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">
      
      <!-- 产生的对象被放在spring中一个成为ioc容器的地方 -->
      <bean id="student" class="claire.entity.Student">
          <property name="stuNo" value="2"></property>
          <property name="stuName" value="ls"></property>
          <property name="stuAge" value="24"></property>
      </bean>
      </beans>
      applicationContext.xml
      package claire.entity;
      
      public class Student {
          private int stuNo;
          private String stuName;
          private int stuAge;
          
          
          
          @Override
          public String toString() {
              return this.stuNo + "," + this.stuName + "," + this.stuAge;
          }
          
          public int getStuNo() {
              return stuNo;
          }
          public void setStuNo(int stuNo) {
              this.stuNo = stuNo;
          }
          public String getStuName() {
              return stuName;
          }
          public void setStuName(String stuName) {
              this.stuName = stuName;
          }
          public int getStuAge() {
              return stuAge;
          }
          public void setStuAge(int stuAge) {
              this.stuAge = stuAge;
          }
      }
      Student.java
      package claire.test;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      import claire.entity.Student;
      
      public class Test {
          public static void main(String[] args) {
              ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              Student bean = (Student)context.getBean("student");
              System.out.println(bean);
          }
      }
      Test.java

      结果:

    3. *Test.java中的ApplicationContext是应用上下文,它继承自BeanFactory接口,有三个常用实现类:
      1. ClassPathXmlApplicationContext: 该类从指定类路径中寻找指定xml文件,找到并装载完成ApplicationContext的实例化工作。
      2. FileSystemApplicationContext: 该类从指定的文件系统中寻找指定xml文件,找到并装载完成ApplicationContext的实例化工作。
      3. XmlWebApplicationContext: 该类从web应用中寻找指定xml文件,找到并装载完成ApplicationContext的实例化工作。
    4. 在java项目中通过ClassPathXmlApplicationContext手工实例化ApplicationContext通常为不二选择,但是在web项目中,web项目的启动是由相应的web服务器负责的,因此,在web项目中ApplicationContext容器的实例化工作最好交由web服务器,spring为此提供了:
      1. 基于ContextLoaderListener实现(在web.xml中加入<context>及<listener>节点并进行相应配置)
      2. 基于ContextLoaderServlet实现(在web.xml中加入<context>及<servlet>节点并进行相应配置)

    bean创建

    package spring_20190115;
    
    public class User {
        private int id;
        private String name;
        
        
        public User() {
            System.out.println("创建了一个user对象");
        }
        
        
        public User(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
    
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        
    }
    User.java

     IOC容器底层是利用反射调用无参构造,故而在IOC容器中定义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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="user" class="spring_20190115.User">
        </bean>
    </beans>

     如此配置等同于

    <bean id="user" class="spring_20190115.User" scope="singleton"></bean>

     单例模式对于无会话状态的Bean(如DAO,业务逻辑组件)来说,是最理想的选择。

    package spring_20190115;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class APP {
        @Test
        public void testApp() throws Exception{
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            User user = (User)ac.getBean("user");
            User user2 = (User)ac.getBean("user");
        }
        
    }
    APP.java

    • 改为多例:
      • <bean id="user" class="spring_20190115.User" scope="prototype"></bean>

      • 单例模式下默认在创建容器时救创建所有单例对象,如果希望在第一次访问的时候才创建,可通过设置bean标签的lazy-init="true"实现(只对单例模式有效);多例模式(原型模式)下时访问才会创建对象, Spring不能对一个原型模式Bean的整个生命周期负责,容器在初始化,装配好一个原型模式实例后,就将它交由客户端不再过问,因此,客户端需要负责原型模式实例的生命周期管理 。                                                                                                                        。

    bean的生命周期

    • singleton  单例

                   1) 创建对象

                       如果有配置延迟初始化,

                          lazy-init=true  如果单例的对象有配置延迟初始化, 在创建容器之后,在第一次从容器获取对象的时候

                                      创建单例的对象!

                      如果没有配置或延迟初始化为默认值, 单例的对象会在创建容器的时候创建对象

                  2) 执行初始化方法 , init-method配置的方法会执行

                  3) 调用容器destroy() 方法时候,容器在销毁单例对象的实例的时候,会调用destroy-method对应的方法

                     此时bean对象会被销毁!

     

    • prototype  多例

                    1) 每次在从容器获取对象的时候,都会创建新的对象

                    2) 每次创建完对象后,就执行初始化方法

                    3) java会回收不用资源(jvm gc)      


    创建对象的方式

    1. 调用无参构造器
    2. 调用有参构造器(因为不管什么类型都是直接放到双引号中,难以区分,建议配合type/name属性使用)
      • <?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:p="http://www.springframework.org/schema/p"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
            <!-- 调用无参构造器 -->
            <bean id="user" class="spring_20190115.User" lazy-init="true"></bean>
        
            <!-- 调用有参构造器-->
            <bean id="str" class="java.lang.String">
                <constructor-arg value="Jack"></constructor-arg>
            </bean>
            <bean id="user2" class="spring_20190115.User">
                <constructor-arg index="0" type="int" value="1000"></constructor-arg>
                <!-- ref 当引用的是IOC容器中的对象的时候,使用ref   -->
                <constructor-arg index="1" type="String" ref="str"></constructor-arg>
            </bean>
        </beans>
        package spring_20190115;
        
        public class User {
            private int id;
            private String name;
            
            
            public User() {
                System.out.println("无参构造器");
            }
            
            
            public User(String name) {
        //        super();
                System.out.println("一个参数构造器");
                this.name = name;
            }
        
        
            public User(int id, String name) {
                System.out.println("两个参数构造器");
                this.id = id;
                this.name = name;
            }
        
            @Override
            public String toString() {
                // TODO Auto-generated method stub
                return this.name+"---"+this.id;
            }
        
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            
            
        }
        User.java
        package spring_20190115;
        
        import org.junit.Test;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;
        
        public class APP {
            @Test
            public void testApp() throws Exception{
                ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
                //无参构造
                User user = (User)ac.getBean("user");
                System.out.println(user);
                
                User user2 = (User) ac.getBean("user2");
                System.out.println(user2);
                //有参构造
                User user3 = (User) ac.getBean("user3");
                System.out.println(user3);
                
            }
            
        }
        App.java
    3. 工厂方法  
      1. 静态方法
      2. 非静态方法
      3. package spring_20190115;
        
        /**
         * 创建user对象工厂
         * @author claire
         *
         */
        public class UserFactory {
            /**
             * 非静态工厂方法
             * @return user对象
             */
            public User getInstance(){
                return new User(100, "工厂非静态方法,创建对象");
            }
            
            /**
             * 静态工厂方法
             * @return
             */
            public static User getStaticInstance(){
                return new User(100, "工厂静态方法,创建对象");
            }
        }
        UserFactory .java
        <?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:p="http://www.springframework.org/schema/p"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
            <!-- 工厂静态方法创建对象 -->
            <bean id="user" class="spring_20190115.UserFactory"
                factory-method="getStaticInstance">
            </bean>
            
            <!-- 非静态方法创建对象 -->
            <bean id="factory" class="spring_20190115.UserFactory"></bean>
            <bean id="user2" factory-bean="factory" factory-method="getInstance"></bean>
        </beans>
        applicationContext.xml
    4. 反射

    处理对象依赖关系的方式

    即给对象的属性赋值的方式:

      1. 构造函数赋值
      2. 自动装配(见下只适用于引用类型ref)
      3. 注解实现自动装配
      4. p名称空间(Spring 3.0以后的特性): xmlns:p="http://www.springframework.org/schema/p"
        <!--方式三: p名称空间 -->
            <bean id="str" class="java.lang.String">
                <constructor-arg value="Summer"></constructor-arg>
            </bean>
            <bean id="user" class="spring_20190115.User" p:id="1000" p:name-ref="str"> </bean>
      5. set方式注入
        1.  普通字段赋值 
          <!-- set方式注入属性值-->
              <bean id="user" class="spring_20190115.User">
                  <property name="id" value="1000"></property>
              </bean>
        2. 集合属性 (list/map/property)

          <!-- list集合属性赋值 -->
                  <property name="list">
                      <list>
                          <value>happy, summer, sunshine</value>
                          <value>flower</value>
                      </list>
                  </property>

          <property name="map">
                      <map>
                          <entry key="1" value="name"></entry>
                      </map>
                  </property>

          <property name="props">
                      <props>
                          <prop key="cn">China</prop>
                          <prop key="usa">America</prop>
                      </props>
                  </property>

       * 特殊符号注入问题:

          使用实体引用(&lt表示"<", &amp表示"&" )或者用<![CDATA[]]>标记,进行原样输出。

      * 给对象赋值null: <property name="name"><null/></property> 

    案例:

    Dao/service/action实例,处理依赖关系

      • package claire.di;
        
        public class UserDao {
            //模拟保存对象
            public void save(){
                System.out.println("UserDao.save()");
            }
        }
        UserDao.java
        package claire.di;
        
        public class UserService {
            //创建dao对象:单例,启动创建
            //接收IOC容器注入
            private UserDao userDao;
        
            public void save(){
                userDao.save();
            }
            
            public UserDao getUserDao() {
                return userDao;
            }
        
            public void setUserDao(UserDao userDao) {
                this.userDao = userDao;
            }
            
            
        }
        UserService
        package claire.di;
        
        public class UserAction {
            private UserService userService;
        
            public String execute() {
                userService.save();
                return "success";
            }
        
            public UserService getUserService() {
                return userService;
            }
        
            // 接收IOC容器注入
            public void setUserService(UserService userService) {
                this.userService = userService;
            }
        
        }
        UserAction
        package claire.di;
        
        import org.junit.Test;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;
        
        public class APP {
            
            private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", APP.class);
            @Test
            public void testApp() throws Exception{
                //从容器中获取action实例
                UserAction userAction = (UserAction) ac.getBean("userAction");
                //执行方法
                userAction.execute();
            }
            
        }
        APP
      • 属性注入
        • 方式一:通过set方法注入,最为常用
          <!-- 方式一:通过set方法注入,最为常用 -->
              <bean id="userDao" class="claire.di.UserDao"></bean>
              <bean id="userService" class="claire.di.UserService">
                  <property name="userDao" ref="userDao"></property>
              </bean>
              <bean id="userAction" class="claire.di.UserAction" scope="prototype">
                  <property name="userService" ref="userService"></property>
              </bean>
        • 方式二:内部bean
          <!-- 更为紧凑,当创建的对象不被其他地方引用时可以这样写,这样写不通用,内部对象只能用一次 -->
              <bean id="userAction" class="claire.di.UserAction" scope="prototype">
                  <property name="userService">
                      <bean class="claire.di.UserService">
                          <property name="userDao">
                              <bean class="claire.di.UserDao"></bean>
                          </property>
                      </bean>
                  </property>
              </bean>
        • 方式三: p名称空间在<beans>标签内部加入 xmlns:p="http://www.springframework.org/schema/p"
          <bean id="userDao" class="claire.di.UserDao"></bean>
              <bean id="userService" class="claire.di.UserService"
                  p:userDao-ref="userDao"></bean>
              <bean id="userAction" class="claire.di.UserAction"
                  p:userService-ref="userService"></bean>
        • 方式四:自动装配(简化配置,但是维护困难,不推荐使用)自动寻找IOC其他bean的id/type
          • 方式一:配置到全局:
            <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
                xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd"
                default-autowire="byName"
                <!-- 也可以直接在此处加入default-autowire="byName" 配置到全局-->
                ></beans>
          • 方式二:配置到bean节点
            <!-- 自动装配 -->
                <bean id="userDao" class="claire.di.UserDao"></bean>
                <!-- byName:根据类中的set方法名(去掉"set"子字符串后),查找容器内是否有同名对象 -->
                <bean id="userService" class="claire.di.UserService" autowire="byName"></bean>
                <!-- byType:根据类中set方法参数的类型到容器中查找相同类型对象 -->
                <!-- byType:使用byType时要保证容器内只有唯一一个对应类型,否则会报NoUniqueBeanDefinitionExpection -->
                <bean id="userAction" class="claire.di.UserAction" autowire="byType"></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:p="http://www.springframework.org/schema/p"
                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
                    http://www.springframework.org/schema/context/spring-context.xsd"
                >
                <!-- 注解方式实现Spring IOC容器配置 -->
                <!-- 开启注解扫描 -->
                <context:component-scan base-package="claire.di"></context:component-scan>
            </beans>
            applicationContext.xml
            package claire.di;
            
            import org.springframework.stereotype.Component;
            import org.springframework.stereotype.Repository;
            
            //第一种方式
            //等于<bean id="userDao" class="..."></bean>
            //@Component("userDao") 
            //第二种方式
            //@Repository("userDao")
            //第三种方式: 省略名称,默认是类名,第一个字母小写,即userDao
            @Repository
            public class UserDao {
                //模拟保存对象
                public void save(){
                    System.out.println("UserDao.save()");
                }
            }
            UserDao.java
            package claire.di;
            
            import javax.annotation.Resource;
            
            import org.springframework.stereotype.Component;
            import org.springframework.stereotype.Repository;
            import org.springframework.stereotype.Service;
            
            //@Component("userService") //将当前类加入ioc容器
            //@Service("userService")
            @Service
            public class UserService {
                
                @Resource  //会默认根据这个属性的名称去容器找,如果找不到,会根据类型找,再没找到即报错。
                private UserDao userDao;
            
                public void save(){
                    userDao.save();
                }
                
                
            }
            UserService .java
            package claire.di;
            
            import javax.annotation.Resource;
            
            import org.springframework.context.annotation.Scope;
            import org.springframework.stereotype.Component;
            import org.springframework.stereotype.Controller;
            
            //@Component("userAction")
            //@Controller("userAction")
            @Controller
            @Scope("prototype")
            
            public class UserAction {
                
                @Resource(name = "userService") //这么写需要set方法
                private UserService userService;
            
                public String execute() {
                    userService.save();
                    return "success";
                }
                
                public void setUserService(UserService userService) {
                    this.userService = userService;
                }
            
            }
            UserAction .java
            package claire.di;
            
            import org.junit.Test;
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            
            import spring_20190115.User;
            
            public class APP {
                
                private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", APP.class);
                @Test
                public void testApp() throws Exception{
                    //从容器中获取action实例
                    UserAction userAction = (UserAction) ac.getBean("userAction");
                    //执行方法
                    userAction.execute();
                }
                
            }
            APP .java
          • 注解总结:简化配置,不利于后期维护,如果修改对象创建、关系处理,需要改代码!

            • @Component  表示一个组件(类),把当前组件加入ioc容器。加入容器的组件的名称默认是类名第一个字母小写

            • @Component(“”)   指定加入ioc容器的组件类的类名,可细化位:

              • @Repository    标识是一个持久层的组件(dao层注解)

              • @Service       标识是一个业务逻辑层的组件(service层注解)

              • @Controller     标识是一个控制层的组件

            • @Scope("prototype")     指定对象单例/多例

            • @Resource     1. 默认根据修饰的字段名称会取ioc容器找对象自动注入。找到后注入

                                       2. 如果名称没有找到,再根据类型查找  找到后就立刻注入。 如果改类型在ioc容器中有多个对象,报错!

                                       3. 根据类型也没有找到对象,报错!

            • @Resource(name =””) 会根据指定的名称去容器找对象自动注入

            • @Autowired: 作用相当于@Resource,不同在于Autowired默认按照bean的类型进行装配,而Resource默认按照bean实例名称进行装配。

    Spring与struts2整合:

    action的创建,交给spring的ioc容器。

    额外引入jar文件:

    spring-web-4.3.9.RELEASE.jar          spring源码】

    struts2-spring-plugin-2.5.14.1.jar         struts源码】

    整合完整步骤:

            1.  引入jar

                     Struts核心jar

                     Spring    Core  核心       (5个)

                      Web  对web支持 (2个)

            2. 配置

      • applicationContext.xml
        <bean id="userAction" class="claire.web.action.UserAction"></bean>
      • struts.xml:
        • <!-- 在action配置中,class属性直接引用spring容器中的对象 -->
                  <action name="user" class="userAction">
                      <result>/index.jsp</result>
                  </action>
      • web.xml
        •  struts2核心过滤器
              <!-- 配置structs2的全局过滤器 -->
              <filter>
                  <filter-name>struts2</filter-name>
                  <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>struts2</filter-name>
                  <url-pattern>/*</url-pattern>
              </filter-mapping>
        • 启动时候,配置加载springIOC容器(在index.html中ctrl+F搜索convenient ApplicationContext即可,但是记得更改路径加入classes如下)
              <!-- 配置spring -->
              <context-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
              </context-param>
              <listener>
                  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
              </listener>
  • 相关阅读:
    《Effective C++》第8章 定制new和delete-读书笔记
    《TCP/IP详解卷1:协议》第3章 IP:网际协议(2)-读书笔记
    【剑指Offer】14合并两个排序的链表
    【剑指Offer】13反转链表
    【剑指Offer】12链表中倒数第k个结点
    【剑指Offer】11调整数组顺序使奇数位于偶数前面
    【剑指Offer】10数值的整数次方
    【剑指Offer】09二进制中1的个数
    【剑指Offer】08矩形覆盖
    【剑指Offer】07变态跳台阶
  • 原文地址:https://www.cnblogs.com/clairexxx/p/10260976.html
Copyright © 2020-2023  润新知