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>
原文地址:https://www.cnblogs.com/clairexxx/p/10260976.html