Java小白自学Spring框架(一)

一、什么是Spring

        Spring框架是JavaEE中的轻量级框架,所谓轻量级框架是相对于重量级框架而言的一种程序设计模式,与重量级框架相比,解决问题的侧重点不同。

         轻量级框架一般由Spring、Struts、Hibernate组成,侧重于减少开发的复杂度,相对它的处理能力也有所减弱(如:事务处理偏弱,不具备分布式处理),比较适用开发中的中小型企业应用。

          Spring以IoC(控制反转)、AOP(面向切面)为主要思想。

  •  控制反转:在Spring框架中,通过配置类对象,在Spring运行阶段进行实例化和组装对象;
  •  面向切面:AOP技术利用一种名为“横切”的技术,剖解开封装的内部对象,并将那些影响了多个类的公共行为封装到一个可重用的模块,并命名为“Aspect”,即为方面。简单来说,就是将与业务无关却又为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块的耦合度,并有利于未来的可操作性和可维护性。

  Spring同时也是一个“一站式”框架,即Spring在JavaEE中的三层架构:表现层(Web层)、业务逻辑层(Service层)、数据访问层(Dao层),每一层提0供了不同的解决技术。如下:

  • 表现层(Web层):Spring MVC
  • 业务逻辑层(Service层):控制反转(IOC)
  • 数据访问层(Dao层):JdbcTemplate

二、控制反转(IoC)

           控制反转(Inversion of Control,英文缩写为IoC)是一种概念,是把我们程序中类与类之间的依赖关系交给容器去处理。

  •  IoC通过两种方式实现其功能:

   依赖查找 DL(dependency lookup):程序提供查找方式,交给容器通过回调函数的方式去查找

   依赖注入 DI(dependency injection):程序不提供查找方式,但提供合适的构造方法或者setter方法,让容器进行注入来解决依赖关系

  •  IoC入门案例

      (1)、导入Spring框架中的相关jar包,搭建Spring项目的开发环境。

       org.springframework:spring-expression:4.3.18.RELEASE
        org.springframework:spring-core:4.3.18.RELEASE
        org.springframework:spring-context:4.3.18.RELEASE
        org.springframework:spring-beans:4.3.18.RELEASE
        log4j:log4j:1.2.17
        commons-logging:commons-logging:1.2

        (2)、首先我们创建一个普通的Java类User类,并创建其方法;如下

public class User {
    public void add(){
        System.out.println("Bean.User and Method.");
    }
    public String toString(){
        return "This is a user object.";
    }
}

     (3)、然后创建Spring的配置文件,进行对Bean的配置

 注意:Spring的配置文件名称和路径是可以自定义的,但官方推荐名称为applicationContext.xml,并且放到src目录下。                        

<?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">
    <!--相当于User user = new Bean.User();-->
    <bean id="user" class="Bean.User"/>   </beans>

      (4)、最后我们创建一个测试类TestIoC来测试一下     

public class TestIoC {
    ApplicationContext ac;
    public void runUser(){
        //加载我们的配置文件
        ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取到user对象
        User user = (User)ac.getBean("user");
        //调用user对象的方法
        user.add();
    }}       

                                     利用Spring配置文件实例化Bean的多种方式

    1、使用类的无参构造创建:

   <bean id = "Bean的对象名" class ="Bean的路径"></bean>’

                      等同于‘Bean bean = new Bean();’

    2、使用静态工厂创建:

    ‘<bean id = "Bean的对象名" class = "工厂类的路径" factory-method="实例化对象方法"></bean>’

                      等同于Bean bean = 工厂类.实例化对象的方法; 

          3、使用实例工厂创建:

   ‘<bean id = "工厂对象名" class = "工厂类的路径"></bean>’

    ‘<bean id = "Bean对象名" class = "工厂类名" factory-method="实例化对象方法"></bean>’

                      等同于Bean bean = 工厂类名.实例化对象方法;

                   Bean标签的常用属性

    1、id属性:指定配置对象的对象名称,不能包含特殊字符

   2、class属性:配置对象所在类的全路径

    3、name属性:同id属性,但name允许包含特殊字符

    4、scope属性:

      singleton:默认值,单例;单例模式下,程序只能由一个实例

      prototype:多例;非单例模式下,每请求该Bean就会产生一个对象

      request:创建对象后将对象存入request域中

      session:创建对象后将对象存入session域中

      globalSession:创建对象后将对象存入globalSession域中 

  •  属性注入

             属性注入值创建对象时向类对象的属性设置属性值

     在Spring框架中支持set方法注入和有参构造函数注入

     有参构造函数注入:采用有参构造函数创建对象并初始化属性

     创建Student类

public class Student {
    private String name;
    public Student(String name){
        this.name = name;
    }
    @Override
    public String toString() {
        return "String{" +
                "name = " +name+'\''+
                '}';
    }
}

     配置Bean标签

<!--通过有参构造进行属性注入-->
<bean id = "student" class= "Bean.Student">
    <constructor-arg name="name" value="zhangsan"/>
</bean>

     测试

public void runStudent(){
    ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) ac.getBean("student");
    System.out.println(student);
}

    set方法注入:创建对象后通过set方法设置属性

     Teacher类

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

    @Override
    public String toString() {
        return "Teacher{" +
                "name = " +name+'\''+
                '}';
    }
}

    配置Bean标签

<!--通过set方法进行属性注入-->
<bean id = "teacher" class = "Bean.Teacher">
    <property name = "name" value="lisi"></property>
</bean>

     测试

public void runTeacher(){
    ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    Teacher teacher = (Teacher) ac.getBean("teacher");
    System.out.println(teacher);
}
  • 注入对象类型属性

       以三层架构中的server层和dao层为例,为了让service层使用dao层的类创建对象,需要将dao层对象注入到service层中。步骤如下:

    (1)、创建Dao类,Dao层接口,Service类

     Dao层接口

public interface UserDao {
    void add();
}

     Dao接口的实现类

public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("UserDaoImpl");
    }
}

     Service类

public class UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
    public void add(){
        System.out.println("UserService");
        userDao.add();
    }
}

   (2)、在配置文件中注入关系

<!--配置Service和Dao对象-->
<!--由于是Service依赖于Dao,所以要先配置Dao对象-->
<bean id = "userDaoImpl" class = "dao.Impl.UserDaoImpl"></bean>
<bean id = "userService" class = "service.UserService">
    <!--
    注入dao对象
    name属性值为:Service某一属性的名称
    ref属性值为:被引用的对象对应bean标签的id值
    -->
    <property name="userDao" ref="userDaoImpl"></property>
</bean> 

   (3)、测试

public void runUserService(){
    ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = (UserService)ac.getBean("userService");
    userService.add();
}
  • P命名空间注入属性 

         之前提到了通过有参构造注入属性和set方法注入属性,现在介绍另一种方式,P命名空间注入属性,步骤如下:

     首先在核心配置文件中加一条

xmlns:p="http://www.springframework.org/schema/p"

     然后用bean标签配置

<!--通过p命名空间注入-->
<bean id = "teacher" class = "Bean.Teacher" p:name = "TeaCher lisi"></bean>
  • 注入复杂类型属性

    通过bean标签向对象中注入复杂类型属性,如:数组,List,Map,Properties

    创建PropertyDemo类

public class PropertyDemo {
    private String[] args;
    private List<String> list;
    private Map<String,String> map;
    private Properties properties;
    public String[] getArgs() {
        return args;
    }
    public void setArgs(String[] args) {
        this.args = args;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Map<String, String> getMap() {
        return map;
    }
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}
    配置bean标签     
<bean id = "propertyDemo" class = "Bean.PropertyDemo">
    <!--注入数组-->
    <property name="args">
        <list>
            <value>value i of Array</value>
            <value>value ii of Array</value>
            <value>value iii of Array</value>
        </list>
    </property>
    <!--注入list集合-->
    <property name = "list">
        <list>
            <value>value i of List</value>
            <value>value ii of List</value>
            <value>value iii of List</value>
        </list>
    </property>
    <!--注入Map集合-->
    <property name = "map">
        <map>
            <entry key = "keyi" value = "value i of Map"/>
            <entry key = "keyii" value = "value ii of Map"/>
            <entry key = "keyiii" value = "value iii of Map"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key = "username">root</prop>
            <prop key = "password">1</prop>
        </props>
    </property>
</bean>

    测试

@Test
public void runPropertyDemo(){
    ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    PropertyDemo propertyDemo = (PropertyDemo)ac.getBean("propertyDemo");
    System.out.println(Arrays.toString(propertyDemo.getArgs()));
    System.out.println(propertyDemo.getList());
    System.out.println(propertyDemo.getMap());
    System.out.println(propertyDemo.getProperties());
}
  • IoC与DI之间的关系

   控制反转(IoC):将传统的创建对象的流程交于框架进行创建和管理,在Spring中,对象的创建方式包括依赖注入(DI),依赖注入不能单独存在,需建立在IoC的基础上完成操作。

  • SpringIoC注解注入

        注解是Java中特殊的标记,通过注解可以实现特定的功能;注解可以使用在类、方法和属性上,格式如下:@注解名或@注解名(属性名 = 属性值)。

案例:

    1、所需的spring基本jar包:commons-logging、log4j、spring-beans、spring-context、spring-core、spring-expression

    2、所需spring的aop包:spring-aop

    3、创建类、方法

public class User {
    public void add(){
        System.out.println("Bean.User and Method.");
    }
    public String toString(){
        return "This is a user object.";
    }
}

    4、创建spring配置文件,引入约束,开启注解扫描

<?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: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">
    <!--
    开启注解扫描
        (1)扫描包中类、方法、属性上是否有注解
    -->
    <context:component-scan base-package="spring"></context:component-scan>
    <!--
        (2)只扫描属性上的注解
    -->
    <!--
    <context:annotation-config></context:annotation-config>
    -->
</beans>

    5、在类上使用@Component注解

@Component(value = "user")
public class User {

    6、创建测试类测试

public class TestAnno {
    ApplicationContext ac;
    @Test
    public void runUser(){
        ac = new ClassPathXmlApplicationContext("annotation.xml");
        User user = (User)ac.getBean("user");
        user.add();
    }
}

    除上面提到的@Component注解之外,spring还提供了@Component的三个衍生注解,其功能一致,都是为了创建对象

  • @Controller:主要声明web层的控制类
  • @Service:主要声明service层的服务类
  • @Repository:主要声明dao层的类组件

注解注入属性

    案例:创建service类和dao类,在service类中注入dao对象

    1、创建dao对象

@Repository(value = "userDao")
public class UserDao {
    public void add() {
        System.out.println("UserDao");
    }
}

    2、创建service对象,并在service对象中定义dao对象类型属性,并使用注解注入

@Service(value = "userService")
public class UserService {
    /**
     * @Autowired
     * 自动注入
     * 通过类名找到对应的类对象进行注入
     * 也可以使用@Resource(name = "userDao")
     * 其中name的值为注解创建Dao对象的value值
     * 这两种注解方式都不一定需要为注入的属性定义et方法
     */
    @Autowired
    private UserDao userDao;
    public void add(){
        System.out.println("UserService");
        userDao.add();
    }
}

    3、测试

@Test
public void runService(){
    ac = new ClassPathXmlApplicationContext("annotation.xml");
    UserService userService = (UserService)ac.getBean("userService");
    userService.add();
}

注:一般配置文件和注解混合使用,创建对象的操作一般用配置文件的方式实现而注入属性的操作一般用注解。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值