Spring整合日志框架以及Spring核心控制反转依赖注入(下)(第三节)

免费内容(初学,复习,和就业前,知识回顾)
Spring工厂模式的实现

学习中如果有想要了解的知识和不会的可以评论留言,尽最大可能帮助你们,也会把问题的答案免费发布出来供提问的和其他人参考
章语
世事多因忙中错,好人半自苦中来。
永远别放弃,哪怕所有人都放弃了你。 --恠咖


请认真仔细阅读发布的内容,有很多实战开发中的细节,很容易忽视掉

此文档连续更新中,所有框架内容以及微服务架构开发和实战项目
1,Spring概述以及第一个Spring(第一章)
2,Spring整合日志框架以及Spring核心控制反转依赖注入(第二章上内容多正在整理)
3,Spring整合日志框架以及Spring核心控制反转依赖注入(中)
4,Spring整合日志框架以及Spring核心控制反转依赖注入(下)(第四节)
下次更新
学完注入和对象创建,接下来就要进入复杂类型创建和源码刨析。还有一些零碎的只是,配置文件参数化,整合YML 自定义类型转换器,即将步入Spring第二个核心AOP以及原理分析,整合Mybatis和事务,使用注解开发

持续更新

复杂类型的注入

学完了简单类型的注入,下面来学习复杂类型的注入,也就是以对象作为属性值,也可以理解为在创建的类中再创建一个类代码演示

步骤
1. 实体类
2. DAO层
3. Service层
4. 配置文件
5. 测试类

步骤

实体类

public class User {
    private String Username;
    private String Password;

    public String getUsername() {
        return Username;
    }

    public void setUsername(String username) {
        Username = username;
    }

    public String getPassword() {
        return Password;
    }

    public void setPassword(String password) {
        Password = password;
    }
}

DAO层接口

import com.pojo.User;

public interface UserDAO {
    //模拟插入数据
    void Save(User user);
}

DAO层实现类

import com.pojo.User;

public class UserDAOImpl implements UserDAO {
    public void Save(User user) {
        System.out.println("insert into User(username,password) values('wang','0701')");
    }
}

Service层接口

import com.pojo.User;

public interface UserService {
    void Save(User user);
}

Service实现层

import com.dao.UserDAO;
import com.pojo.User;

public class UserServiceImpl implements UserService {
    private UserDAO userDAO;

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void Save(User user) {
        userDAO.Save(user);
    }
}

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="com.pojo.User"/>
    <bean id="userService" class="com.service.UserServiceImpl">
        <property name="userDAO" >
            <bean class="com.dao.UserDAOImpl"/>
        </property>
    </bean>
</beans>

这里的属性值对应的是ServiceImpl里的

private UserDAO userDAO;
//可以理解为
UserDAO userDAO = new UserDAOImpl();
//将创建UserDAOImpl对象赋值给userDAO类型为UserDAO

配置文件

<property name="userDAO"></property> ==== private UserDAO userDAO
<bean class="com.dao.UserDAOImpl"/> 创建一个对象没有指定id 赋值给userDAO

测试类

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

public class UserTest {

    @Test
    public void userTest(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/ApplicationContext03.xml");
        UserService userService = ctx.getBean("userService", UserService.class);
        User user = ctx.getBean("user", User.class);
        user.setUsername("admin");
        user.setPassword("0701");
        userService.Save(user);
    }
}

运行结果
在这里插入图片描述

以上就是创建复杂类型的步骤,按照分层的方式简单的进行模拟整合Mybatis按照MVC的架构进行开发,后面也会有整合Mybatis ,等以及其他框架内容.

思考分析

这种注入属性有什么缺陷?

第一种赋值方式存在的问题

1. 配置文件代码冗余
2. 被注入的对象(UserDAO),多次创建,浪费(JVM)内存资源
    <bean id="user" class="com.pojo.User"/>
    <bean id="userService" class="com.service.UserServiceImpl">
        <property name="userDAO" >
            <bean class="com.dao.UserDAOImpl"/>
        </property>
    </bean>

第二种注入复杂类型的方式

其他代码不需要改变只需要修改配置文件即可

    <bean id="userDAO" class="com.dao.UserDAOImpl"/>
    <bean id="userService" class="com.service.UserServiceImpl">
        <property name="userDAO">
          <bean ref="userDAO"/>
        </property>
    </bean>

可以把创建的对象属性单独提取出来然后通过ref进行引用,这也是开发中常用的一种方法

也可以简化为

  <bean id="userDAO" class="com.dao.UserDAOImpl"/>
<bean id="userService" class="com.service.UserServiceImpl">
        <property name="userDAO" ref="userDAO"/>
    </bean>

构造注入

1. Set注入:Spring调用Set方法,通过配置文件,为成员变量赋值
2. 构造注入:Spring调用构造方法,通过配置文件,为成员变量赋值

实体类

import java.util.List;

public class Constructor {
    private String Username;
    private int age;
    private List<String> hobby;

    public Constructor(String username, int age, List<String> hobby) {
        Username = username;
        this.age = age;
        this.hobby = hobby;
    }

    public String getUsername() {
        return Username;
    }

    public void setUsername(String username) {
        Username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobby() {
        return hobby;
    }

    public void setHobby(List<String> hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Constructor{" +
                "Username='" + Username + '\'' +
                ", age=" + age +
                ", hobby=" + hobby +
                '}';
    }
}

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="constructor" class="com.jing.Constructor">
        <constructor-arg name="username" value="admin"/>
        <constructor-arg name="age" value="18"/>
        <constructor-arg name="hobby">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

测试类

import com.jing.Constructor;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConstructorTest {

    //构造注入
    @Test
    public void Constructortest(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/ApplicationContext04.xml");
        Constructor constructor = ctx.getBean("constructor", Constructor.class);
        System.out.println(constructor);
    }
}

运行结果
在这里插入图片描述

对象注入

<bean id="userService" class="com.service.UserServiceImpl">
        <constructor-arg ref="userDAO"/>
    </bean>

构造注入的其他方式

根据index进行注入

以索引0开始

<bean id="constructor" class="com.jing.Constructor">
        <constructor-arg index="0" value="admin"/>
        <constructor-arg index="1" value="18"/>
        <constructor-arg index="2">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </constructor-arg>
    </bean>

根据数据类型进行注入

<bean id="constructor" class="com.jing.Constructor">
        <constructor-arg type="java.lang.String" value="admin"/>
        <constructor-arg type="int" value="18"/>
        <constructor-arg type="java.util.List">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </constructor-arg>
    </bean>

直接传值

直接给参数赋值,这种方法也是根据顺序排的,所以一旦调换位置的话,就会出现bug,这种方法已经很原始了,了解即可。

<bean id="constructor" class="com.jing.Constructor">
        <constructor-arg value="admin"/>
        <constructor-arg value="18"/>
        <constructor-arg>
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </constructor-arg>
    </bean>

以上就是构造注入的方法Set集合,Map集合和set注入写法如出一辙,可以自己进行练习,最好的学习方法就是坚持和复习.

注入总结

在实际开发中最常用的还是根据name进行注入,也是推荐的一种使用方法。

以下图用来展示如何选用注入方式
在这里插入图片描述

p命名空间和c命名空间

p命名空间和c命名空间

在通过构造方法或set方法给bean进行注入时,是通过constructor-arg元素和property元素来定义的,而p命名空间和c命名空间就是新的一种写法进行注入,功能上并没有什么区别,只是在写法上进行了简化,需要注意的是Spring的版本必须在3.1及以上

p命名空间
使用p命名空间时需要先声明使用对应的命名空间,即在beans元素上加入xmlns:p=“http://www.springframework.org/schema/p”,以下就是p命名空间的使用方法 格式:普通属性 p:属性名=”值” 对象属性 p:属性名-ref=”值”*,必要条件需要有set方法

<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
  <!--原始的写法-->
    <bean id="classic" class="com.pojo">
        <property name="email" value="9685@qq.com"/>
    </bean>
<!--使用p命名空间注入普通属性-->
    <bean id="p-namespace" class="com.pojo" p:email="8544@qq.com"/>
<!--使用p命名空间注入对象属性-->
        <bean id="userDAO" class="com.dao.UserDAOImpl"/>
    <bean id="userService" class="com.service.UserServiceImpl" p:userDAO-ref="userDAO"/>
</beans>

需要注意的是p命名空间和c命名空间只使用于8种基本数据类型+String 和自定义类型

c命名空间

c命名空间在实现的功能上和p命名空间完全相同,唯一的区别就是p命名空间是通过set进行注入的而c命名空间则是通过构造方法注入的

格式:普通属性 c:属性名=”值” 对象属性 c:属性名-ref=”值”*,必要条件需要有构造方法其他与p命名空间的用法如出一辙。

<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
  <!--原始的写法-->
    <bean id="classic" class="com.pojo">
        <property name="email" value="9685@qq.com"/>
    </bean>
<!--使用c命名空间注入普通属性-->
    <bean id="p-namespace" class="com.pojo" c:email="8544@qq.com"/>
<!--使用c命名空间注入对象属性-->
        <bean id="userDAO" class="com.dao.UserDAOImpl"/>
    <bean id="userService" class="com.service.UserServiceImpl" c:userDAO-ref="userDAO"/>
</beans>

复合属性

复合属性即嵌套属性可以理解为,为对象属性指定其属性值例:

<bean id="student" class="com.jing.Student" >
 </bean>
 <bean id="attribute" class="com.jing.Attribute">
  <property name="student" ref="student"/>
  <property name="student.name" value="小飞"/>
 </bean>

如果嵌套的对象属性中还有属性的话还可以通过.(点)继续赋值 下面举个简单的完整的例子

步骤

1. 教师类
2. 学生类
3. 成绩类
4. 配置文件

教师类

public class Teacher{
    private String tname;
    
    public void setTeacher(String tname){
        this.tname = tname;
    }
    public String getTeacher(){
        return tname;
    }
}

学生类

public class Student{
    private String sname;
    private Teacher teacher;
    public void setStudent(String sname){
        this.sname = sname;
    }
    public String getStudent(){
        return sname;
    }
}

成绩类

public class Score{
    private int score;
    private Student student;
    public void setScore(int score){
        this.score=score;
    }
    public int getScore(){
        return score;
    }
}

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="student" class="com.jing.Student"/>
    
    <bean id="score" class="com.jing.Score">
    <property name="score" value="95"/>
    <property name="student" ref="student"/>
    <property name="student.sname" value="小飞"/>
    <property name="student.teacher.tname" value="李老师"/>
    </bean>
</beans>

以上就是复合属性很少这样用,官方文档中也有一个例子不过描述的不是很清楚。

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离落&恠咖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值