Spring(一)Spring的基本应用

控制的什么被反转了?就是获得依赖对象的方式被反转了——Martin Fowler

1、Spring基本知识

 1.1 什么是Spring?

  • Spring是分层JavaSE/EE full-stack轻量级开源框架
  • IoC(Inverse of Control,控制反转)和AOP(Aspect Oriented Programing,面向切面编程)为核心
  • 实际开发中,通常采用三层体系架构(web、service、dao)。spring对每一层都提供了技术支持,在表示层提供了与struts2框架的整合,在业务逻辑层可以管理事务、记录日志等,在持久层可以整合Hibernate、JdbcTemplate等技术

 1.2 Spring框架的优点

  • 方便解耦,简化开发  (高内聚低耦合)  Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理spring工厂是用于生成bean
  • AOP编程的支持                   Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  • 声明式事务的支持                只需要通过配置就可以完成对事务的管理,而无需手动编程
  • 方便程序的测试                                   Spring对Junit4支持,可以通过注解方便的测试Spring程序
  • 方便集成各种优秀框架                                  Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
  • 降低JavaEE API的使用难度                          Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

 1.3 Spring的体系结构 

  

        核心容器:beanscorecontextexpression

 1.4 Spring的下载及目录结构

  下载地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/3.2.0.RELEASE
  目录结构:

    

  libs中有50多个jar文件,有4个Spring的基础包,分别对应Spring核心容器的4个模块

    

          spring-core-3.2.0.RELEASE.jar           包含Spring框架基本的核心工具类,Spring其他组件都要用到这个包里的类,是其他组件的基本核心
     spring-beans-3.2.0.RELEASE.jar        所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行IoC或者DI操作相关的类
     spring-context-3.2.0.RELEASE.jar      在基础IoC功能上的扩展服务
     spring-expression-3.2.0.RELEASE.jar   定义了Spring的表达式语言

2. 入门案例:IoC

 2.1 导入jar包   4核心+1依赖    

  

 2.2 目标类

  UserDao接口

public interface UserDao {
    public void addUser();
}

  UserDaoImpl实现类

public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }
}

 2.3 配置文件

  spring帮我们创建对象,但也必须有相关类的信息,不然怎么能够创建呢?

  配置文件名称:建议:ApplicationContext.xml,取别的也可以,但是取建议的名称的话,找到该配置文件更为简单,

  配置文件位置:任意,一般都在classpath下(src)

  文件约束内容:添加约束,spring-framework-3.2.0.RELEASE 为spring的核心  docs为帮助文档

  约束位置:spring-framework-3.2.0.RELEASEdocsspring-framework-referencehtmlxsd-config.html

 

<?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="userDao" class="com.tcxpz.spring_chapter01.ioc.UserDaoImpl"></bean>
</beans>

 2.4 测试

public class TestIoC {
    @Test
    public void demo(){
        /*
         * 以前的做法是 UserDao userDao = new UserDaoImpl()
         * 现在交给Spring来创建,程序从Spring容器中获取
         */
        //1 定义配置文件的路径(项目中一般放在src目录下,此处为方便放在包下)
        String xmlPath = "com/tcxpz/spring_chapter01/ioc/applicationContext.xml";
        //2 初始化Spring容器,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        //3 通过容器获取userDao实例
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        //调用userDao的addUser()方法
        userDao.addUser();
    }
}

  测试结果:

    

3 入门案例2:DI

  依赖注入(DI):spring创建对象A时,会将对象A所依赖的对象B也创建出来,并自动注入到对象A中。

  依赖:(has a) 有一个的意思,比如类A中有一个类B,那么就说A依赖B。          

  继承,实现:(is a)

  当出现一个类依赖于另一个类时,之前的开发是这样的

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    @Override
    public void save() {
        userDao.addUser();
    }
}

  学习了Spring之后,开发就是这样的了

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.addUser();
    }
}

 3.1 导入jar包(同2.1)

 3.2 目标类

  UserDao接口与UserDaoImp实现类(同2.2)

  UserService接口与UserServiceImpl实现类

public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.addUser();
    }
}

 3.3 配置文件

<?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">
      <!-- 创建UserDao对象 -->
    <bean id="userDao" class="com.tcxpz.spring_chapter01.di.UserDaoImpl"></bean>
    <!-- 创建Service对象 -->
    <bean id="userService" class="com.tcxpz.spring_chapter01.di.UserServiceImpl">
    <!--  
    <property> 用于进行属性注入
            name: bean的属性名,通过setter方法获得
                setBookDao ##> BookDao  ##> bookDao
            ref :依赖的另一个bean的id值的引用
    -->
        <property name="userDao" ref="userDao"></property>
    </bean>
</beans>

 

3.4 测试

public class TestDI {
    @Test
    public void demo(){
        String xmlPath = "com/tcxpz/spring_chapter01/di/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.save();
    }
}

 测试结果

4 Spring中的bean

4.1 Bean的配置

可以把Spring看做一个大型的工厂,而Spring容器中的bean就是该工厂的产品

Spring容器支持两种格式的文件,分别为Properties文件格式和XML文件格式,在实际开发中,最常用的是XML文件格式的配置方式

每一个<bean>子元素定义了一个bean,并且描述了该bean如何被装配到Spring容器中。<bean>中包含很多属性:id,name,class,scope,constructor-arg,property,ref,value,list,set,map,entry

4.2 Bean的实例化

并不是每个bean都是普通类,有些是通过工厂来获取的,而工厂就有静态工厂和实例工厂,所以spring创建实例对象有三种情况,

  默认无参构造:直接<bean id="" class="">,必须提供无参的构造方法

  静态工厂:由于是静态工厂,所以通过工厂类直接调用创建实例的静态方法就可以了,不需要创建工厂的实例对象。

        <bean id="" class="工厂全限定类名" factory-method="静态方法">

  实例工厂:需要先创建出工厂实例对象,然后再由工厂实例对象的方法创建对象,所以会有两个Bean

          <bean id="myFactoryId" class="工厂全限定类名"></bean>

          <bean id="" factory-bean="myFactoryId"  factory-method=""></bean>

4.3 Bean的作用域

  作用域的种类:singleton  prototype  request  session  global

    

    主要掌握前两个即可

单例模式(singleton):使用singleton定义的Bean在Spring容器中只有一个实例,也就是说,无论有多少个Bean引用它,始终指向同一个对象(默认作用域) 

public class TestDI {
    @Test
    public void demo(){
        String xmlPath = "com/tcxpz/spring_chapter01/di/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService1 = (UserService) applicationContext.getBean("userService");
        UserService userService2 = (UserService) applicationContext.getBean("userService");
        System.out.println(userService1==userService2);
    }
}

原型模式(prototype):每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的实例。

4.4 Bean的生命周期

  Spring容器可以管理singleton作用域下Bean的生命周期,再次作用于下,Spring能够精确地知道该何时创建,何时初始化完成,以及何时被销毁。

  而对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管,Spring容器就不再跟踪其生命周期。

4.5 Bean的装配方式

  Bean的装配可以理解为依赖关系注入,Bean的装配方式也就是Bean依赖注入的方式。主要有三种:基于XML      基于注解      自动装配

  4.5.1 基于XML的装配

    主要有两种方式:setter注入和构造注入   setter注入时,Bean类必须提供一个默认的构造方法,而且必须为注入的属性提供setter方法
    (1)导包   4核心+1依赖

    (2)创建User类

public class User {
    private String username;
    private Integer password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Integer getPassword() {
        return password;
    }
    public void setPassword(Integer password) {
        this.password = password;
    }
    //默认构造
    public User(){
    }
    //构造方法注入
    public User(String username,Integer password){
        super();
        this.username=username;
        this.password=password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }    
}

    (3)测试

public class TestUser {
    @Test
    public void demo(){
        String xmlPath="com/tcxpz/spring_chapter01/domain/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        User user1 = (User) applicationContext.getBean("user1");
        User user2 = (User) applicationContext.getBean("user2");
        System.out.println(user1);
        System.out.println(user2);
    }
}

  不管是普通属性还是引用数据,都可以通过构造方法进行注入。通过setter方法进行注入引用数据。

  

  通过setter方法对普通属性和引用属性进行注入,那么要是创建的对象中有集合呢?那该如何进入注入?

         集合的注入List、Map、Set、数组、Properties等。

  list

    

  set

    

  map

    

  数组:

    

  properties

    

    注意:集合之间可以相互嵌套,比如list中可能装有对象(bean)等等

      

  4.5.2 基于Annotation的装配    

    注解格式:@xxx       开发中通常采用注解取代xml配置文件

    使用注解:必须对使用注解的地方进行扫描,不然注解没用。而扫描需要做两件事

      1、添加名称空间

         在我们找配置文件中约束的位置那:spring-framework-3.2.0.RELEASEdocsspring-framework-referencehtmlxsd-config.html 找到context的名称空间。

         

        

      2. 扫描指定的目录

        

    注解:

      1、@Component  替代  <bean id="" class=""> 可以配置任意bean,在所在类上面添加该注解即可,

         @Component("userId") userId相当于bean中的id属性值

      2、这三个就跟使用@Component是一样的,但是为了更好的体现三层架构,就有了这三个注解

         @Controller  修饰web层中的类。

         @Service  修饰service层的类

         @Repository  修饰dao层的类

            两种方式,一种不声明名称,一种声明名称

            @Controller("xxx")  @Controller  

            如果声明了名称,那么在别的地方引用的话,就可以使用@Autowired或@Autowired与@Qualifier的组合 或直接使用@Resource按照名称注入

            如果没有声明名称,那么在别的地方引用的话,只能使用@Autowired 来进行注入

      3、属性注入

         普通属性

            @Value    @Value("")  给普通属性注入属性值

          引用属性

              @Autowired  按默认类型进行注入

              @Qualifier("") 按照名称注入  

            如果使用了@Qualifier这个注解,那么就需要两个一起使用才能生效。如果只使用@Autowired,那么写不写@Qualifier都可以

          引用属性

            @Resource  直接按照名称注入,与上面两个注解一起使用是等效的  

            @Resource(name="xxx")

      4、使用

        

      5、其他注解

        @Scope("prototype")  作用域注解(spring帮我们创建的bean实例的作用域,在下面会讲解到)

        @PostConstruct  修饰初始化    

        @PreDestory  修饰销毁      

                最后两个用的不多,掌握前面的即可。

  4.5.3 P命令空间[了解]

  对setter方法注入”进行简化,替换<property name="属性名">,而是在<bean p:属性名="普通值"  p:属性名-ref="引用值">

  p命名空间使用前提,必须添加命名空间

     

    <bean id="personId" class="com.itheima.f_xml.c_p.Person" 
        p:pname="jack" p:age="22" 
        p:homeAddr-ref="homeAddrId" p:companyAddr-ref="companyAddrId">
    </bean>
    
    <bean id="homeAddrId" class="com.itheima.f_xml.c_p.Address"
        p:addr="北京" p:tel="010">
    </bean>
    <bean id="companyAddrId" class="com.itheima.f_xml.c_p.Address"
        p:addr="合肥" p:tel="0551">
    </bean>

  4.5.4 SpEL[了解]

  <property>进行统一编程,所有的内容都使用value

  <property name="" value="#{表达式}">

    #{123}#{'jack'} : 数字、字符串

    #{beanId} :另一个bean引用

    #{beanId.propName} :操作数据

    #{beanId.toString()} :执行方法

    #{T().字段|方法} :静态方法或字段

5 myeclipse schema xml提示

 步骤一:确定xsd文件位置:spring-framework-3.2.0.RELEASEschemaeans

步骤二:复制路径

步骤三:搜索“xml catalog”

步骤四:添加约束提示

  

        

原文地址:https://www.cnblogs.com/tcxpz/p/9751799.html