Spring IOC\AOP\事务\注解

一、引言


1.1 原生web开发中存在哪些问题?
  • 传统Web开发存在硬编码所造成的过度程序耦合(例如:Service中作为属性Dao对象)。

  • 部分Java EE API较为复杂,使用效率低(例如:JDBC开发步骤)。

  • 侵入性强,移植性差(例如:DAO实现的更换,从Connection到SqlSession)。

总结:代码的耦合度太高 操作数据库比较复杂 移植性差

1.2 解决方案
目标:
  A.降低代码是耦合度  UserService 与UserDao紧密联系
  B.把创建对象的主动权交给容器 由容器来创建对象以及管理对象  
解决:
  A.使用反射来创建对象
  B.使用map容器来存储对象
  C.使用配置文件来保存对象的信息 在运行期间编译修改

step01 新建配置文件

userDao=com.qf.dao.UserDaoImpl
userService=com.qf.service.impl.UserServiceImpl

step02 新建一个工厂类

package com.qf.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class BeanFactory {
   
    //用于加载配置文件
    private static Properties properties;
    //定义一个容器来管理对象
    private static Map<String,Object> map;

    static {
   
        //实例化Properties 对象
        properties = new Properties();
        InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        //加载配置文件
        try {
   

            properties.load(is);
            //实例化Map集合
            map = new HashMap<String, Object>();
            //获取所有的key
            Enumeration<Object> enume = properties.keys();
            //使用循环遍历
            while (enume.hasMoreElements()){
   

                    //获取key
                    String key = enume.nextElement().toString();
                    //获取value值
                    String  value = properties.getProperty(key);
                    //通过反射来实例化对象
                    Class cla = Class.forName(value);
                    //创建对象
                    Object o = cla.newInstance();
                    //将对象存入容器中
                    map.put(key,o);

            }
        } catch (IOException e) {
   
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        } catch (InstantiationException e) {
   
            e.printStackTrace();
        } catch (IllegalAccessException e) {
   
            e.printStackTrace();
        }


    }

    //根据key获取值
    public static  Object  getObject(String key){
   
        return  map.get(key);
    }



}

step03 测试类

package com.qf.test;

import com.qf.service.UserService;
import com.qf.utils.BeanFactory;

public class Test {
   
    public static void main(String[] args) {
   
        //获取Userservice对象
//        UserService userService = (UserService) BeanFactory.getObject("userService");
//       // System.out.println(userService);
//        userService.add();

        for (int i=0;i<=5;i++){
   
            UserService userService = (UserService) BeanFactory.getObject("userService");
            System.out.println(userService);

        }

    }
}

二、Spring框架


2.1 概念
  • Spring是一个项目管理框架,同时也是一套Java EE解决方案。
  • Spring是众多优秀设计模式的组合(工厂、单例、代理、适配器、包装器、观察者、模板、策略)。
  • Spring并未替代现有框架产品,而是将众多框架进行有机整合,简化企业级开发,俗称"胶水框架"。
  • Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益
2.2 访问与下载

官方网站:https://spring.io/

三、Spring架构组成


Spring架构由诸多模块组成,可分类为

  • 核心技术:依赖注入,事件,资源,i18n,验证,数据绑定,类型转换,SpEL,AOP
  • 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient。
  • 数据访问:事务,DAO支持,JDBC,ORM,封送XML。
  • Spring MVC和 Spring WebFlux Web框架。
  • 集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
  • 语言:Kotlin,Groovy,动态语言。
  • IOC 控制反转 DI 依赖注入
  • AOP 动态代理
  • spring jdbcTemplate
  • spring事物管理

请添加图片描述

请添加图片描述

四、Spring Framework 体系

在这里插入图片描述

五 Spring 搭建

5.1 搭建

step01 导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.18</version>
        </dependency>
    </dependencies>

在这里插入图片描述

step02创建spring 配置文件 applicationConext.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="userService" class="com.qf.service.UserService"></bean>

</beans>

step03 测试类

package com.qf.test;

import com.qf.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test01 {
   
    public static void main(String[] args) {
   
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object userService = app.getBean("userService");
        System.out.println(userService);
        UserService userService1 = app.getBean("userService", UserService.class);
        System.out.println(userService1);

        UserService userService2 = app.getBean("userService", UserService.class);
        System.out.println(userService2);

    }
}

5.2 执行流程

在这里插入图片描述

六 Spring 控制反转(IOC)

6.1 控制反转

在这里插入图片描述
在这里插入图片描述

6.2 Bean的管理
6.2.1 使用默认的构造方法实例化对象

注意点:这种方式最常用 但是类中必须定义无参构造方法(特别是注解的时候)

6.2.2 使用工厂实例化

在很多情况下,对于第三方的代码或之前的老代码,很可能对象的创建是通过工厂来完成的。对于工厂创建出的对象交给spring容器管理。

step01 新建一个工厂类

package com.qf.utils;

import com.qf.entity.Student;
import com.qf.service.UserService;

public class BeanFactory {
   
     Student stu(){
   
        return   new Student();
     }

}

step02 新建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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <!--工厂对象-->
      <bean id="beanFactory" class="com.qf.utils.BeanFactory" ></bean>
    <!--需要工厂类创建对象 由 spring进行管理-->
    <!--
         factory-bean  找到spring容器创建这个对象的工厂
         factory-method 创建对象的方法
      -->
    <bean id="student" factory-bean="beanFactory" factory-method="stu"></bean>
</beans>


step03 测试类

package com.qf.test;

import com.qf.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test02 {
   
    public static void main(String[] args) {
   
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("bean01.xml");
        Student s = app.getBean("student", Student.class);
        System.out.println(s);
    }
}



6.2.3 使用静态工厂实例化

ste01 新建一个静态工厂类

package com.qf.utils;

import com.qf.entity.Student;

public class StudentFactory {
   
    public static Student getStudent(){
   
       return  new Student();
    }
}



step02 修改配置文件

<?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="beanFactory" class="com.qf.utils.BeanFactory" ></bean>-->
    <!--需要工厂类创建对象 由 spring进行管理-->
    <!--
         factory-bean  找到spring容器创建这个对象的工程
         factory-method 创建对象的方法
      -->
<!--    <bean id="student" factory-bean="beanFactory" factory-method="stu"></bean>-->

    <bean id="stu" class="com.qf.utils.StudentFactory" factory-method="getStudent"></bean>


</beans>


step03 测试类

package com.qf.test;

import com.qf.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test02 {
   
    public static void main(String[] args) {
   
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("bean01.xml");
        Student s = app.getBean("stu", Student.class);
        System.out.println(s);
    }
}



6.2.4 bean的作用范围

业务层和持久层、表现层(Servlet、Filter等)对象一般使用单例对象。实体类一般使用多例对象。使用spring框架不用再自己编写单例模式了。默认情况下,交给spring容器管理的对象就是单例对象。

singleton:表示这个 bean 是单例的,默认即此。

  • prototype:表示这个 bean 多多例的,每次从容器中获取 bean,都会拿到一个全新的 bean
    下面这三个 scope ,在 web 环境下生效(将来我们学了 SpringMVC 之后,就可以使用这三个了)。
  • request:在同一个请求中,拿到的始终是同一个对象。
  • session:在同一个会话中,拿到的始终是同一个对象。
  • application:在应用重启之前,拿到的始终是同一个对象。

代码-配置文件

<?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="actor" class="com.qf.entity.Actor"></bean>

</beans>


代码-测试类

package com.qf.test;

import com.qf.entity.Actor;
import com.qf.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test02 {
   
    public static void main(String[] args) {
   
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("bean01.xml");
        Actor a1= app.getBean("actor", Actor.class);
        Actor a2= app.getBean("actor", Actor.class);
        System.out.println(a1==a2);

    }
}



6.2.5 bean生命周期中的两个特殊方法

初始化方法:是在构造方法执行后执行。

销毁方法:销毁对象之前执行。 (由jvm执行 由gc来进行垃圾回收)

step01 修改类

package com.qf.entity;

public class Actor {
   

    public   Actor(){
   
        System.out.println("执行了构造方法......");
    }
    public void init(){
   
        System.out.println("初始化");
    }

    public   void  destroy(){
   
        System.out.println("销毁");
    }

}



step02 配置文件

<?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="actor" class="com.qf.entity.Actor" scope="prototype"  
          init-method="init" destroy-method="destroy"></bean>

</beans>


七 spring依赖注入

7.1 依赖注入简介
1.依赖注入Dependency Injection 简称DI和IoC 是一回事。指原来自己创建对象,现在让别人传给你,就相当于注入进来。
2.依赖注入有两种方式 A.通过构造方法  B.通过set方法


7.2 依赖注入-构造方法

step01 新建User类

package com.qf.entity;

public class User {
   
    private  Integer uid;
    private  String uname;

    public User() {
   
    }

    public User(Integer uid, String uname) {
   
        this.uid = uid;
        this.uname = uname;
    }
}



step02 编写配置文件

<?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="com.qf.entity.User">
        <!--通过构造方法注入值
              name 表示属性名
              value 表示属性值
         -->
        <constructor-arg name="uid" value="10"/>
        <constructor-arg name="uname" value="张三"/>
    </bean>


</beans>


step03 修改测试类

package com.qf.test;

import com.qf.entity.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test01 {
   
    public static void main(String[] args) {
   
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);

    }
}



7.3 依赖注入-set方法注入

step01 修改类 添加set get方法

step02 修改配置文件

<?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="u" class="com.qf.entity.User">
        <property name="uid" value="12"></property>
        <property name="uname" value="您好"></property>
    </bean>


</beans>


7.4 依赖注入 -注入其它类型

step01 新建一个类

package com.qf.entity;

import java.util.*;

public class Person {
   
    private Date bornDate;
    private String[] hobbys;
    private Set<String> phones;
    private List<String> names;
    private Map<String,String> countries;
    private Properties files;
    //注入自定义对象
    private  User user;

    public Date getBornDate() {
   
        return bornDate;
    }

    public void setBornDate(Date bornDate) {
   
        this.bornDate = bornDate;
    }

    public String[] getHobbys() {
   
        return hobbys;
    }

    public void setHobbys(String[] hobbys) {
   
        this.hobbys = hobbys;
    }

    public Set<String> getPhones() {
   
        return phones;
    }

    public void setPhones(Set<String> phones) {
   
        this.phones = phones;
    }

    public List<String> getNames() {
   
        return names;
    }

    public void setNames(List<String> names) {
   
        this.names = names;
    }

    public Map<String, String> getCountries() {
   
        return countries;
    }

    public void setCountries(Map<String, String> countries) {
   
        this.countries = countries;
    }

    public Properties getFiles() {
   
        return files;
    }

    public void setFiles(Properties files) {
   
        this.files = files;
    }

    public User getUser() {
   
        return user;
    }

    public void setUser(User user) {
   
        this.user = user;
    }

    @Override
    public String toString() {
   
        return "Person{" +
                "bornDate=" + bornDate +
                ", hobbys=" + Arrays.toString(hobbys) +
                ", phones=" + phones +
                ", names=" + names +
                ", countries=" + countries +
                ", files=" + files +
                ", user=" + user +
                '}';
    }
}




step02 新建一个配置文件

<?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="com.qf.entity.User">
        <property name="uid" value="11"></property>
        <property name="uname" value="kkk"></property>
    </bean>

    <bean id="person" class="com.qf.entity.Person">
       <property name="bornDate" value="2010/11/23"/>
       <property name="hobbys">
           <array>
               <value>kkkkk</value>
               <value>wwww</value>
           </array>
       </property>

        <property name="phones">
            <set>
                <value>111111</value>
                <value>222222</value>
            </set>
        </property>

        <property name="names">
           <list>
               <value>3333333</value>
               <value>4444444</value>
           </list>
        </property>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值