美文网首页我爱编程
Spring第一天(IOC,DI)

Spring第一天(IOC,DI)

作者: 原来蜗牛不是牛 | 来源:发表于2017-07-17 23:13 被阅读0次

    什么是Spring

    1. 是进行对象管理,对象关联,解耦的一个中间层框架
    2. 是一个轻量级的IOC和AOP容器框架:
    • 轻量级:程序实现不是很复杂,代码不是很多,占用资源不是很多,没有侵入性;
    • IOC(Inversion of Control 控制反转):对象创建责任的反转(重点,核心)
    • AOP(Aspect Oriented Programming):一种面向横切面编程的思想方式,可以进行功能性扩展
    • 容器:可以容纳对象,并且可以控制对象的生命周期;
    1. 核心思想:IOC思想-控制反转,DI思想-依赖注入

    耦合

    回忆一下,在没有使用Spring框架时,业务层和持久层之间的调用
    例:
    持久层:UserDao/UserDaoImpl
    业务层:UserService/UserServiceImpl
    要在业务层调用持久层的方法时的做法:

    public class UserServiceImpl implements UserService {
        private UserDao UserDao = new UserDaoImpl();//此处即耦合了    
        @Override
        public boolean addUser(Car car) {       
            return 0;
        }
    }
    

    解耦

    1. IOC思想:创建对象的工作交给Spring管理
    2. DI思想:Spring创建好的对象给需要的层(类)使用

    IOC开发流程

    1. 在maven项目的pom.xml文件中添加spring的依赖
    <!-- 添加Spring包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency> 
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        
        <!-- 为了方便进行单元测试,添加spring-test包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
    
    1. 编写接口和实现类
      规范要求:面向接口编程
      编写LoginService接口
    public interface LoginService {
        void login();
    }
    

    编写LoginServiceImpl实现类

    public class LoginServiceImpl implements LoginService {
        @Override
        public void login() {
            System.out.println("登录成功!!!");
        }   
    }
    
    1. 编写Spring的核心配置文件
      在src根目录下创建applicationContext.xml文件,这就是Spring的核心配置文件
    <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 definitions here -->
        <!-- IOC:Spring来创建服务层对象 -->
        <bean id="loginService" class="com.qf.service.LoginServiceImpl"></bean>
        <!--LoginService loginService =new  LoginServiceImpl()-->   
    </beans>
    
    1. 测试
    //加载配置
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    //得到指定的Bean(得到指定的对象)
    LoginService loginService = (LoginService)ac.getBean("loginService");
    //调用方法
    loginService.login();
    

    生命周期

    Spring的生命周期在配置文件中自定义

    <bean id="loginservice" class="org.cx.spring01.LoginServiceImpl" init-method="myinit" destroy-method="mydestroy" scope="prototype"></bean>
    

    在对应类里面实现init-method="myinit" destroy-method="mydestroy"指定的方法

    public void myinit(){
            System.out.println("初始化方法!");
        }
        public void mydestroy(){
            System.out.println("销毁方法!!");
        }
    

    作用域

    默认创建对象的方式是单例模式
    想改变创建对象的方式为多例模式,添加scope="prototype"属性

    DI(依赖注入)

    联想到生活中的场景:USB接口
    程序中:
    服务层依赖持久层
    表现层依赖服务层
    依赖的部分交给 Spring管理。
    创建对象使用 IOC
    关联使用:DI注入

    依赖注入的方式

    set方法注入:在类中给需要注入的属性添加setter方法
    依赖的对象使用ref来关联。通过 id唯一标示进行查找

    • 编写持久层DAO接口和实现类
    public interface UserinfoDao {
        void addUser();
        void findUser();
    }
    
    public class UserinfoDaoImpl implements UserinfoDao {
    
        public void addUser() {
            // TODO Auto-generated method stub
            System.out.println("addUser");
            
        }
    
        public void findUser() {
            // TODO Auto-generated method stub
            System.out.println("findUser");
        }
    }
    
    • 编写服务层service接口和实现类
    public interface UserinfoService {
        //服务层可以暴露给其他团队使用。
        //http访问不到
        //其他团队可以直接使用接口
        //Java开发工程师:服务端开发。
            
        void addUser();
        
        void findUser();
        
        void sendMsg(); 
    }
    
    public class UserinfoServiceImpl implements UserinfoService {
        //依赖持久层DAO
        private UserinfoDAO userinfoDAO;
        //依赖判断条件
        //把条件做成可配置
        private String tag;
        private boolean execute;
    
        //SpringDI set注入会调用这个方法
        public void setUserinfoDAO(UserinfoDAO userinfoDAO) {
            this.userinfoDAO = userinfoDAO;
        }
        public void setTag(String tag) {
            this.tag = tag;
        }
        public void setExecute(boolean execute) {
            this.execute = execute;
        }
    
        public void addUser() {
            userinfoDAO.addUser();
        }
    
        public void findUser() {
            userinfoDAO.findUser();
        }
    
        public void sendMsg() {
            System.out.println("send.....");
            //满足某种业务条件后做一次添加
            userinfoDAO.addUser();
        }
    
    • 编写Spring核心配置文件
      • 引入对象的注入
        <!-- 1.IOC:创建持久层DAO对象,id唯一bi某个bean,某个对象-->
        <bean id="userinfoDAOID" class="com.qf.dao.UserinfoDAOImpl"></bean>
        <!-- 2,IOC:创建服务层service对象 -->
        <bean id="userinfoService" class="com.qf.service.UserinfoServiceImpl">
        <!-- 3,DI:把DAO对象注入给service使用 -->
        <property name="userinfoDAO" ref="userinfoDAOID"></property>
        </bean>
    
    • 基本属性注入
    <!-- 2,IOC:创建服务层service对象 -->
        <bean id="userinfoService" class="com.qf.service.UserinfoServiceImpl">
        <!-- 3,DI:把DAO对象注入给service使用 -->
        <property name="userinfoDAO" ref="userinfoDAOID"></property>
        <!-- 简单类型可以直接用value赋值 -->
        <property name="tag" value="sendmsg" ></property>
        <property name="execute" value="true"></property>       
        </bean>
    

    构造器注入:在类中要提供带需要注入参数的构造方法

    • 名称识别注入(推荐)
      <constructor-arg name="tag" value="sendmail" ></constructor-arg>
    • 索引识别注入
      <constructor-arg index="0" value="sendmail" ></constructor-arg>

    集合注入

    集合可以在本地内存做缓存。提高性能。

    1. 数组注入
    <property name="ids">
       <array>
           <value>税源</value>
           <value>赵玉磊</value>
           <value>廖英杰</value>
           <value>文强</value>
           <value>唐蠡海</value>
       </array>
    </property>
    
    1. List集合注入(底层相当于一个可改变长度的数组)
    <property name="list">
        <array>
            <value>权亮</value>
            <value>余斌</value>
            <value>蒋帅</value>
            <value>张祎</value>
            <value>邓鹏</value>
        </array>
    </property>
    
    1. Map注入
    <property name="map">
        <map>
            <entry key="刘庆" value="真帅"></entry>
            <entry key="陈懿" value="真棒"></entry>
            <entry key="陈枭" value="就是帅"></entry>
            <entry key="张岩" value="就是美"></entry>
            <entry key="程波涛" value="涛涛江水"></entry>
        </map>
    </property>
    
    1. Set注入
    <property name="set">
        <set>
            <value>徐可</value>
            <value>朱文东</value>
            <value>王家豪</value>
            <value>车思韬</value>
            <value>曹伟</value>
        </set>
    </property>
    

    5.Properties注入

    <property name="properties">
        <props>
            <prop key="陈潮瀚">真汉子</prop>
            <prop key="陈田">小甜甜</prop>
            <prop key="朱文东">小东东</prop>
            <prop key="苗元">CEO</prop>
            <prop key="周锐">锐锐</prop>
            <prop key="曾限端">端端</prop>
            <prop key="李鹏万">旺旺</prop>
        </props>
    </property>
    

    回忆各种集合的遍历方式

    注解

    注解是Spring的配置另一种方式
    持久层,业务层,表现层都可以使用注解

    • 持久层替换
    @Repository(value="bookDAO")//对应<bean id="bookDAO" class="com.qf.dao.BookDAOImpl"></bean>
    public class BookDAOImpl implements BookDAO {
    
        public void addBook() {
            System.out.println("addBook...");
        }
    }
    
    • 服务层替换
    @Service(value="bookService")
    public class BookServiceImpl implements BookService {
        //依赖持久层:
        @Autowired
        @Qualifier("bookDAO")//唯一定位使用哪个DAO
        private BookDAO bookDAO;
        
        @Value(value="add")//注入属性
        private String tag;
    
        public String getTag() {
            return tag;
        }
    
        public void setTag(String tag) {
            this.tag = tag;
        }
    
        public void setBookDAO(BookDAO bookDAO) {
            this.bookDAO = bookDAO;
        }
    
        public void addBook() {
            if("add".equals(tag)){
                bookDAO.addBook();
            }
        }
    }
    
    • Spring核心配置文件开启注解扫描
    <!-- 开启注解扫描 :把包下面的所有子包下面的所有类进行扫描-->
        <context:component-scan base-package="com.qf"></context:component-scan>
    

    注解配置的方式使用在持久层和业务层会导致:
    1.代码可读性差
    2.依赖属性的值强编码在类中。如果修改,需要重新编译。
    不适合线上操作。
    所以开发中都使用注解加配置文件的方式开发:持久层和业务层使用配置文件的方式,表现层使用注解的方式

    相关文章

      网友评论

        本文标题:Spring第一天(IOC,DI)

        本文链接:https://www.haomeiwen.com/subject/tzmqkxtx.html