ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

(一)Spring-介绍、对象创建以及依赖注入

2022-05-10 18:32:51  阅读:170  来源: 互联网

标签:依赖 Spring User 创建 import com public happy


(一)Spring-介绍、对象创建以及依赖注入

一、 简介

  • spring:春天--->给软件行业带来了春天

  • Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然后,Sping的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

    • 目的:解决企业应用开发的复杂性

    • 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能。

    • 范围:任何Java应用

  • Spring是一个轻量级控制反转(IoC)面向切面(AOP)的容器框架。

  • 官网地址:

    https://spring.io/projects/spring-framework

    https://docs.spring.io/spring-framework/docs/current/reference/html/core.html

1.1 Spring的前生

  • 2002,首次推出了Spring框架的雏形:interface21框架!
  • 2004年3月24号,Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。
  • Rod Johnson,是Spring Framework创始人。
  • Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有技术框架。

1.2 Spring特征

  • 核心技术:依赖注入、事件、资源、i18n、验证、数据绑定、类型转换、SpEL、AOP。
  • 测试:模拟对象、TestContext 框架、Spring MVC 测试、WebTestClient.
  • 数据访问:事务、DAO 支持、JDBC、ORM、编组 XML。
  • Spring MVCSpring WebFlux Web 框架。
  • 集成:远程处理、JMS、JCA、JMX、电子邮件、任务、调度、缓存。
  • 语言:Kotlin、Groovy、动态语言。

1.3 Spring的优点

  • Spring是一个开源的免费的框架(容器)!
  • Spring是一个轻量级的、非入侵式的框架。
  • 控制反转(IoC)面向切面(AOP)
  • 支持事务的处理,对框架整合的支持。

总结:Spring是一个轻量级的控制反转(IoC)面向切面(AOP)的框架

1.4 Spring的组成

1.5 拓展

在Spring的官网有这个介绍:现代化的Java开发!说白了就是基于spring的开发。

  • Spring framework
  • Spring Boot
    • 一个快速开发的脚手架。
    • 基于SpringBoot可以快速的开发单个微服务。
    • 约定大于配置!
  • Spring Cloud
    • SpringCloud是基于SpringBoot实现的

因为现在大多数公司都在使用SpringBoot进行快速开发,学习Springboot的前提,需要完全掌握Spring及SpringMVC!承上启下的作用!

Spring Framework的弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称配置地狱。

二、IOC理论推导

2.1 IOC之前的原来模式

1 UserDao接口

package com.happy.dao;

import com.happy.pojo.User;

public interface UserDao {

    User getUser();
}

2 UserDaoImpl实现类

package com.happy.dao;

import com.happy.pojo.User;
import com.happy.utils.IDutils;

public class UserDaoMysqlImpl implements UserDao {
    @Override
    public User getUser() {
//        模拟数据库查询到用户了
        User user = new User();
        user.setId(IDutils.getId());
        user.setPwd("123");
        user.setName("happy");

        System.out.println("mysql数据库里获取到user了");
        return user;

    }
}

3 UserService业务接口

package com.happy.service;

import com.happy.dao.UserDao;
import com.happy.pojo.User;

public interface UserService {
//    UserDao userDao=null;
    public User getUser();
}

4 UserServiceImpl业务实现类

注意:

  • 使用setUserDao来给外界提供接口注入实现。
package com.happy.service;

import com.happy.dao.UserDao;
import com.happy.dao.UserDaoImpl;
import com.happy.dao.UserDaoMysqlImpl;
import com.happy.pojo.User;

public class UserServiceImpl implements UserService {
    //    UserDao userDao = new UserDaoImpl();
    //    UserDao userDao = new UserDaoMysqlImpl();
    //    UserDao userDao=new UserDaoImpl()
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public User getUser() {
//        UserDao userDao = new UserDaoImpl();

        User user = userDao.getUser();
        return user;
    }
}

5 控制层

package com.happy.servlet;

import com.happy.dao.UserDaoMysqlImpl;
import com.happy.pojo.User;
import com.happy.service.UserService;
import com.happy.service.UserServiceImpl;
import org.junit.Test;

public class TestUserService {

    @Test
    public void testUserService(){
        UserService userService = new UserServiceImpl();
        ((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl());
        User user = userService.getUser();
        System.out.println(user);
    }
}

6 小结

在我们之前的业务中,用户的需求变更或者实现方式变更可能会影响我们原来的代码,我们需要根据变动去修改源代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!

我们使用了一个Set接口实现,对外暴露,已经发生了革命性的变化!

  • 之前,程序是主动创建对象!控制权在程序员手上。
  • 使用set注入后,并给外部暴露接口,程序不再具有主动性,而是等待外部被动的接收对象。

这种思想,从本质上解决了问题,我们程序员不用去手动创建和管理对象了,系统的耦合性大大降低,更加专注业务的实现上。这就是IOC的原型!

public class UserServiceImpl implements UserService {
    //    UserDao userDao = new UserDaoImpl();
    //    UserDao userDao = new UserDaoMysqlImpl();
    //    UserDao userDao=new UserDaoImpl()
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

2.2 IOC本质

  • 控制反转IoC(Inversion of Contorl),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种方法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建移交给第三方,个人认为控制反转就是:获得依赖对象的方式反转了。
  • 采用XML方式配置Bean的时候,Bean的定义信息和实现分离的,而采用注解的方式可以把两者合为一体,bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
  • 控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的事IoC容器,其实现方法时依赖注入(Dependency InJection)

三、Spring入门

3.1 HelloSpring

1 编写bean

package com.happy.pojo;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

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

2 编写xml=》注入bean到容器

<?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="userDaoImpl" class="com.happy.dao.UserDaoImpl"></bean>
    <bean id="userDaoMysqlImpl" class="com.happy.dao.UserDaoMysqlImpl"></bean>
    <bean id="userDaoOracleImpl" class="com.happy.dao.UserDaoOracleImpl"></bean>

    <bean id="userService" class="com.happy.service.UserServiceImpl">
<!--        <property name="userDao" ref="userDaoMysqlImpl"></property>-->
<!--        ref是引用spring容器中创建好的对象-->
        <property name="userDao" ref="userDaoOracleImpl"></property>
    </bean>
</beans>

3 使用bean测试

package com.happy.servlet;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestHelloSpring {

    @Test
    public void testHelloSpring(){

//        ClassPathXmlApplicationContext为ApplicationContext的一个实现
//        获取spring的上下文对象!
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Object hello = context.getBean("hello");
        Object hello2 = context.getBean("hello");
        System.out.println(hello);
        System.out.println(hello==hello2);
    }
}

3.2 UserDao的案例

到此,我们继续根据spring来完善第2部分UserDao的案例

1 编写bean

同第二部分1~4部分,编写Service和Dao层的bean

2 编写xml=》注入bean到容器

<?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="userDaoImpl" class="com.happy.dao.UserDaoImpl"></bean>
    <bean id="userDaoMysqlImpl" class="com.happy.dao.UserDaoMysqlImpl"></bean>
    <bean id="userDaoOracleImpl" class="com.happy.dao.UserDaoOracleImpl"></bean>

    <bean id="userService" class="com.happy.service.UserServiceImpl">
<!--        <property name="userDao" ref="userDaoMysqlImpl"></property>-->
<!--        ref是引用spring容器中创建好的对象-->
        <property name="userDao" ref="userDaoOracleImpl"></property>
    </bean>
</beans>

3 使用bean测试

package com.happy.servlet;

import com.happy.dao.UserDaoMysqlImpl;
import com.happy.pojo.User;
import com.happy.service.UserService;
import com.happy.service.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestUserService {

    @Test
    public void testUserService(){
        UserService userService = new UserServiceImpl();
        ((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl());
        User user = userService.getUser();
        System.out.println(user);
    }


    @Test
    public void testUserServiceBySpring(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("userDao.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        User user = userService.getUser();
        System.out.println(user);
    }
}

四、IOC创建对象方式

4.1 无参构造

默认使用无参构造创建对象,这是默认的。

<bean id="user" class="com.happy.pojo.User"></bean>

4.2 有参构造的3种方式

1 构造器参数下标

    <!--    第一种方式:通过下标index     -->
<bean id="user" class="com.happy.pojo.User">-->
	<constructor-arg index="0" value="gaoyiheng"></constructor-arg>-->
</bean>

2 构造器参数类型

不推荐使用!第二种方式不建议使用,同类型不能精确指定,容易混淆。

<!--    第二种方式:通过下标index     -->
    <!-- 第二种方式不建议使用,同类型不能精确指定,容易混淆-->
<bean id="user" class="com.happy.pojo.User">
      <constructor-arg type="java.lang.String" value="happy518"></constructor-arg>
      <constructor-arg type="java.lang.String" value="happyname"></constructor-arg>
</bean>

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">

    <!--    第三种方式:通过属性的name     -->
    <bean id="user" class="com.happy.pojo.User">
        <constructor-arg name="name" value="gaoxing"></constructor-arg>
        <constructor-arg name="id" value="123"></constructor-arg>
    </bean>
</beans>

五、Spring配置

Spring的配置很少,总共就下面5个一级标签。

5.1 Alias别名

   <bean id="user" class="com.happy.pojo.User">
        <constructor-arg name="name" value="gaoxing"></constructor-arg>
        <constructor-arg name="id" value="123"></constructor-arg>
    </bean>


    <bean id="user2" class="com.happy.pojo.User2" scope="prototype">
    </bean>

    <alias name="user" alias="user1"></alias>
    @Test
    public void testAlias(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("user.xml");
        User user = (User) applicationContext.getBean("user");
        User user1 = (User) applicationContext.getBean("user1");
        System.out.println(user1);
        System.out.println(user==user1);
    }

下图可以看到,两个对象都相等,证明为就是一个别名而已。

另一种起别名的方法

用name

  <bean id="user" class="com.happy.pojo.User" name="user3">
        <constructor-arg name="name" value="gaoxing"></constructor-arg>
        <constructor-arg name="id" value="123"></constructor-arg>
    </bean>

5.2 Bean的配置

1 name

2 scope

指定bean的作用范围。

 <bean id="user" class="com.happy.pojo.User" name="user3">
        <constructor-arg name="name" value="gaoxing"></constructor-arg>
        <constructor-arg name="id" value="123"></constructor-arg>
    </bean>


    <bean id="user2" class="com.happy.pojo.User2" scope="prototype">
    </bean>

5.3 import

  • 这个import,一般用于团队合作开发使用,他可以将多个配置文件导入合并为一个。

  • 假设,现在项目中有多个人开发,这三个复制不同的类开发,不同的类开发,不同的类需要注册在不同的bean.xml文件中。我们可以利用import将所有人的beans.xml合并为一个总的。

  • applicationContext.xml一般为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">
    <import resource="user.xml"></import>
</beans>

六、依赖注入

6.1 构造器注入

见第4章节。

6.2 set属性注入

  • 依赖注入:set注入属性
    • 依赖:属性
    • 注入:bean对象中的所有属性,由容器来注入

1 测试对象bean

package com.happy.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private String name;
    private String wife;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private Properties info;

}

2 依赖属性-复杂对象bean

package com.happy.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {

    private String Address;
}

3 配置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="student" class="com.happy.pojo.Student">
<!--        第一种普通值注入-->
        <property name="name" value="happy"></property>
        <property name="address" ref="addresss"></property>
       <!-- <property name="wife" value="null"></property>-->
        <property name="wife">
            <null></null>
        </property>
        <!--array-->
        <property name="books">
            <array>
                <value>西游记</value>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>
        <!--list-->
        <property name="hobbys">
            <list>
                <value>女</value>
                <value>美女</value>
            </list>
        </property>
        <!--map-->
        <property name="card">
            <map>
                <entry key="信用卡" value="1234"></entry>
                <entry key="储蓄卡" value="4321"></entry>
            </map>
        </property>
        <!--set-->
        <property name="games">
            <set>
                <value>篮球</value>
                <value>足球</value>
            </set>
        </property>
        <!--property-->
        <property name="info">
            <props>
                <prop key="username">happy</prop>
                <prop key="password">12314</prop>
                <prop key="url">jdbc:mysql://localhost/mysql</prop>
            </props>
        </property>
    </bean>
    <!-- 复杂对象-->
    <bean id="addresss" class="com.happy.pojo.Address">
      <property name="address" value="香港"></property>
    </bean>

</beans>

4 测试使用

package com.happy.service;

import com.happy.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Properties;

public class StudentServiceImpl implements StudentService {
    @Override
    public Student getStudent() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("student");
        String wife = student.getWife();
        System.out.println(wife);

        Properties info = student.getInfo();
        System.out.println("info的类型:"+info.getClass());
        System.out.println(info.getProperty("url"));
        info.setProperty("addkey","addvalue");
        System.out.println("info:"+info);

        System.out.println(student);
        return student;
    }

    @Test
    public void test() {
        getStudent();
    }
}

6.3 拓展方式注入:P命名空间和C命名空间

我们可以通过P和C命名空间注入依赖

1 p:

p命名空间注入,可以直接注入属性的值:property

<?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"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.happy.pojo.User" p:name="happybyP" c:pwd="8888">
       <!-- <property name="name" value="happy518"></property>-->
    </bean>

</beans>

2 c:

c命名空间注入,通过构造器注入:constructor-args

<?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"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.happy.pojo.User" c:pwd="8888">
        <property name="name" value="happy518"></property>
    </bean>

</beans>

3 使用测试

package com.happy.service;

import com.happy.pojo.Student;
import com.happy.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Properties;

public class StudentServiceImpl implements StudentService {
    @Override
    public Student getStudent() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("student");
        String wife = student.getWife();
        System.out.println(wife);

        Properties info = student.getInfo();
        System.out.println("info的类型:"+info.getClass());
        System.out.println(info.getProperty("url"));
        info.setProperty("addkey","addvalue");
        System.out.println("info:"+info);

        System.out.println(student);
        return student;
    }

    @Test
    public void test() {
        getStudent();
    }

    @Test
    public void testPandC(){
        ApplicationContext context = new ClassPathXmlApplicationContext("user.xml");
        User user = context.getBean("user", User.class);

        System.out.println(user);

    }
}

注意点:p命名和C命名空间不能直接使用,需要导入xml约束。

标签:依赖,Spring,User,创建,import,com,public,happy
来源: https://www.cnblogs.com/happycarpediem/p/16254782.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有