Spring框架

本文介绍了Spring的核心特性,包括IoC控制反转与DI依赖注入,以及AOP面向切面编程。通过实例演示如何在Spring中使用set注入、注解注入和组件扫描,展示了Spring在简化应用开发中的作用。
摘要由CSDN通过智能技术生成

1.什么是spring

spring是一个开源的轻量级Java开发框架,是一种简化应用程序的开发。

在spring出来之前,service层调用dao都是采用new对象的方法,在spring出来以后,service层和dao都会放在spring容器中去管理,这也是spring的第一种特性,我们称之为IOC,控制反装。

spring还有一种主要的特性,AOP,面向切面,说白了就是专人专事,在项目中有很多公用的模块,例如日志模块等,都可以抽调出来,这就是利用的AOP的特性。

2.spring的特性

spring主要有两大特性

IOC控制反转:DI依赖注入

AOP面向切面

3.spring组成部分

4.spring理念和核心思想

spring理念是面向Bean编程,核心思想是万物都是Bean

5.spring的优势

低侵入式的设计

独立于各种应用服务器

依赖注入将组件关系透明化,降低了耦合度

面向切面编程允许将通用任务集中处理

能够和第三方的框架良好整合

6.实现:

6.1IOC思想

在普通的设计中,在创建好service层和dao层的时候,创建对象采用的是new的方式来new出新的对象

利用spring,可以将其放在spring中,统一管理

首先:导入依赖


  1. <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.5</version>
    </dependency>
  2. 然后创建service层

  3. public interface UserService {
        Integer addUser();
    }
     
     
    public class UserServiceImpl implements UserService{
        @Override
        public Integer addUser() {
            System.out.println("哈哈");
            return null;
        }
    }

    然后在resources中添加配置文件

    applicationContext.xml

     

  4. <?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">
     
        <!-- id是接口名字首字母小写(公约,其他名字也行,相当于new的变量名),class实现类路径 -->
        <bean id="userService" class="cn.kgc.service.UserServiceImpl"></bean>
     
    </beans>
    在测试类中:

    //new一个ClassPathXmlApplicationContext对象
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    //通过getBean方法获取对象
    UserService userService = (UserService)ac.getBean("userService");
    //调用方法
    userService.add();
    可以看出,此时不需要手动new出service对象,而是交给spring容器去管理

    6.2spring的set注入:
    spring的特性:AOP和IOC

    IOC思想:控制反转,不复负责具体实现--->DI(依赖注入)

    DI实现:(set注入,注解注入@,构造器注入,静态工厂注入,动态工厂注入,方法参数注入)

    set注入(属性注入):对象,引用类型,属性,属性值等,又分手工注入ref和自动注入非ref(byName,byType)

    6.2.1属性注入:
    实体类:

    public class User   {
        private Integer id;
        private String name;
     
        public Integer getId() {
            return id;
        }
     
        public String getName() {
            return name;
        }
     
        public void setId(Integer id) {
            System.out.println("调用方法setId......");
            this.id = id;
        }
     
        public void setName(String name) {
            System.out.println("调用方法setName......");
            this.name = name;
        }
    }
    resources/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">
        <bean id="user" class="cn.kgc.entity.User">
            <property name="id" value="1"/>
            <property name="name" value="杨幂"/>
        </bean>
    </beans>
    测试:(在spring中getBean属性注入的时候,调用的是set方法)

    @org.junit.Test
    public void test(){
        //实例化,主要加载地址
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取,需要转类型
        User user = (User) ac.getBean("user");
        System.out.println(user.getId());
    }
    最后在实现的时候,可以发现,一起调用了实体类中的set方法,同时实体类中的属性有了值

    6.2.2 引用类型注入
    手工注入:

    创建两个实体类,User,Role

    其中要有getset方法

    public class User {
        private Integer id;
        private  String name;
        private Role role;
    }
    public class Role {
        private Integer rId;
        private String rName;
    }
    resources/applicationContext.xml:

    <bean id="user" class="cn.kgc.entity.User">
        <property name="id" value="1"/>
        <property name="name" value="杨幂"/>
        <property name="role" ref="role111"/>  ref可以当作一个路径,标识,匹配下面的bean中的id
    </bean>
     
    <bean id="role111" class="cn.kgc.entity.Role">
        <property name="rId" value="11"/>
        <property name="rName" value="迪丽热巴"/>
    </bean>
    测试类:

    @org.junit.Test
    public void testuser(){
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) ac.getBean("user");
        System.out.println(user.getRole().getrName());
    }
    自动注入:

    不用ref,设置自动注入:包括两种方式:btName和byType

    1)byName:

    实体类:

    public class User {
        private Integer id;
        private  String name;
        private Role role;
    }getset方法此处省略,需要添加
    public class Role {
        private Integer rId;
        private String rName;
    }
    byName(按名称注入):
    java类中引用类型的属性名(role)和spring容器中(配置文件)<bean>的id名称一样,

    数据类型是一致的,这样的容器中的bean,spring能够赋值给引用类型
    resources/applicationContext.xml:

    <bean id="user" class="cn.kgc.entity.User" autowire="byName">
            <property name="id" value="1"/>
            <property name="name" value="杨幂"/>
    <!--        <property name="role" ref="role"/>-->
        </bean>
    原先的注释掉,只要名字相同,添加btName,引用类型就能自动匹配
        <bean id="role" class="cn.kgc.entity.Role">
            <property name="rId" value="11"/>
            <property name="rName" value="迪丽热巴"/>
        </bean>
    测试类:

    @org.junit.Test
    public void testuser(){
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) ac.getBean("user");
        System.out.println(user.getRole().getrName());
    }
    2)btType

     byType(按类型注入):
     java类中引用类型的数据类型和spring容器中(配置文件)<bean>的class属性
    是同源关系的,这样的bean能够赋值给引用类型
         
    同源就是一类型的意思:
    第一种同源.java引用类型的数据类型和bean的class的值是一样的
    第二种同源.java引用类型的数据类型和bean的class的值是父子类间的关系
    第三种同源.java引用类型的数据类型和bean的class的值是接口和实现类的关系
    第一种同源(class相同):

    实体类:

    public class User {
        private Integer id;
        private  String name;
        private Role role;
    }getset方法此处省略,需要添加
    public class Role {
        private Integer rId;
        private String rName;
    }
    xml文件:

    <bean id="user" class="cn.kgc.entity.User" autowire="byType">
        <property name="id" value="1"/>
        <property name="name" value="杨幂"/>
    </bean>
    此时不需要添加id也行,同源的类,都是role属性,规约要求添加id
    <bean class="cn.kgc.entity.Role">
        <property name="rId" value="11"/>
        <property name="rName" value="迪丽热巴"/>
    </bean>
    第二种同源(父子类):

    public class User {
        private Integer id;
        private  String name;
        private Role role;
    }getset方法此处省略,需要添加
    public class Role {
        private Integer rId;
        private String rName;
    }
    public class SonRole extends Role{
        
    }
    xml文件:

    <bean id="user" class="cn.kgc.entity.User" autowire="byType">
        <property name="id" value="1"/>
        <property name="name" value="杨幂"/>
    </bean>
    下面设置子类,User类中的Role可以自动获取到子类,同源
    <bean class="cn.kgc.entity.SonRole">
        <property name="rId" value="11"/>
        <property name="rName" value="古力娜扎"/>
    </bean>
    第三种同源(接口):

    接口类:

    mapper中的两个类:接口和实现类
    public interface UserMapper {
        void add();
    }
    public class UserMapperImpl implements UserMapper {
        @Override
        public void add() {
            System.out.println("迪丽热巴");
        }
    }
    service中的两个类:接口和实现类
    public interface UserService {
        void add();
    }
    public class UserServiceImpl implements UserService {
        private UserMapper userMapper;
     
        public UserMapper getUserMapper() {
            return userMapper;
        }
     
        public void setUserMapper(UserMapper userMapper) {
            this.userMapper = userMapper;
        }
     
        @Override
        public void add() {
            userMapper.add();
        }
    }
    xml:

    <bean id="userService" class="cn.kgc.service.UserServiceImpl" autowire="byType"></bean>
     
    <bean id="userMapper" class="cn.kgc.mapper.UserMapperImpl"></bean>
    6.3spring的注解注入:
    @Component        创建对象,等同于Bean功能

    实体类:

    @Data
    @Component(value = "user")
    public class User {
        private Integer id;
        private String name;
    }
     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"
           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 https://www.springframework.org/schema/context/spring-context.xsd">
     
        <!--添加一个扫描器,组件扫描器-->
        <context:component-scan base-package="cn.kgc.entity"/>
    </beans>
    @Repository        用在持久层上面,方法在dao的实现类上面,表示创建dao对象

    @Repository(value = "userMapper") 
    //value中的名字,是后面getBean中的方法名
    public class UserMapperImpl implements UserMapper {
        @Override
        public Integer addUser() {
            System.out.println("访问数据库。。。调用UserMapper的addUser方法......");
            return null;
        }
    }
    此时添加扫描器可以多种方式:

    分号,或者多个标签,或者上级目录全部扫描

    <context:component-scan base-package="cn.kgc.entity;cn.kgc.mapper"/>
    或:
    <context:component-scan base-package="cn.kgc.entity"/>
    <context:component-scan base-package="cn.kgc.mapper"/>
    或:
    <context:component-scan base-package="cn.kgc"/>
     

    @Service        用在业务层上面,放在service的实现类上面,表示创建service对象,可以有一些事务功能

    @Service(value = "userService")
    public class UserServiceImpl implements UserService {
        @Override
        public Integer addUser() {
            System.out.println("调用UserService中的方法");
            return null;
        }
    }
    @Controller        在控制层,相当于servlet,添加注解

    方法同上

    @Value        在实体类中给简单类型的属性添加值,可以免去get set方法

    @Data
    @Component(value = "user")
    public class User {
        @Value("1")
        private Integer id;
        @Value("迪丽热巴")
        private String name;
    }
    @Autowired        给引用类型属性赋值(自动装配Bean),使用,默认使用byType自动注入。

    @Data
    @Component(value = "user")
    public class User {
        @Value("1")
        private Integer id;
        @Value("迪丽热巴")
        private String name;
     
        @Autowired
        private Role role;
    }
     
    @Data
    @Component(value = "role")
    public class Role {
        @Value("11")
        private Integer rId;
        @Value("古力娜扎")
        private String rName;
    }
     

    一共spring提供了上面的几种注解,每个注解用在不同的应用层。

    除此之外,还有一种注解方法,不是spring提供的,是jdk中自带的:Resources

    给引用类型赋值,Spring提供了对JDK注解@Resource的支持,默认按名称注入,如果按名称注入失败,自动按类型注入

    使用方法和Autowired类似
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值