spring入门学习一

1.1简介

  • 春天,spring就是java的春天
  • spring本身就是一个大杂烩,它的理念就是使现有的框架更容易使用,整合了现有的技术框架。说白了spring就是一个整合剂。
  • 开源、免费、轻量级的非入侵式的框架
  • IOC和AOP
  • 对事务的支持,对框架整合的支持

1.2环境搭建

导包

直接导webmvc这个包,可以把其他很多需要的功能包一并导入,

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
</dependencies>

具体的包:
在这里插入图片描述

传统写法的困境

如果传统写法,我们要获取mysql数据库的用户信息,则需要调接口:

package com.mao.service;

import com.mao.dao.UserDao;
import com.mao.dao.UserDaoMySqlImpl;

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoMySqlImpl();

    public void getUser(String username) {
        userDao.getUser(username);
    }
}

然而当实际应用中调用该接口的用户想获取Oracle数据库的用户信息的时候,又不得不该源代码,把UserDaoMySqlImpl()改为UserDaoOracleImpl(),这样的代码显然是及其低效的,所以我们不应该让程序员去控制对象的生成(即对象生成的管理权交给程序员),而应该让客户去调用接口来生成指定的实现类,这就是所谓的控制反转。

IOC本质

控制反转是一种设计思想,而DI(依赖注入)是其一种具体的实现方式。我们在使用面向对象编程的时候,对象的创建及对象的依赖关系完全通过硬编码来实现,而控制翻转则是将依赖的关系管理交给了第三方容器去管理,所以获得依赖的方式反转了。

**控制反转是一种通过描述(XML或者注解)**并通过第三方去生产或获取特定对象的方式。在spring中实现控制反转的是IoC容器,其实现方法是依赖注入。

总结:spring中对象的创建和对象属性的赋值都是由spring容器来执行的。控制反转中的控制就是谁来控制对象的创建,而反转则是程序本身不创建对象,是由主动的编程变成了被动的接收。

注意:其中要注意必须在实体类中有set方法才能给属性注入值

IOC实战

实体类:

package com.mao.pojo;

import lombok.Data;

@Data
public class User {

    private String name;
    private String age;
    private String hobbies;

    public void sayHi(){
        System.out.println("大家好,我的名字叫"+name+",我今年"+age+"岁了,我的爱好是:"+hobbies);
    }
}

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.mao.pojo.User">
        <property name="name" value="童胖"></property>
        <property name="age" value="10"></property>
        <property name="hobbies" value="唱,跳,rap"></property>
    </bean>
</beans>

测试:

package com.mao;

import com.mao.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User)applicationContext.getBean("user");
        user.sayHi();
    }
}

输出:
在这里插入图片描述

IOC创建对象的方式

默认使用无参构造创建对象,想要用有参构造,就要在<bean></bean>中使用construct-arg标签设置

spring配置

别名

<!-- id:bean的唯一标识名,class是指定的类名,name也是别名,还可以指定多个,用“,”分隔 -->
<bean id="user" class="com.mao.pojo.User" name="xvshaoqing,xvshenghui">
        <property name="name" value="童胖"></property>
        <property name="age" value="10"></property>
        <property name="hobbies" value="唱,跳,rap"></property>
    </bean>
<alias name="user" alias="tongpang"></alias>

import导入

ClassPathXmlApplicationContext(String…files)可以指定多个xml配置,然而我们开发中也可以在一个xml配置文件中引入多个配置文件,相当于多合一了,如:

<!-- 这是application.xml文件 -->
<import resource="beans.xml">

通过以上方式就把beans.xml引入到了applicaiton中了。

DI依赖注入

有三种实现方式:

一、构造器注入

通过构造器为属性赋值

二、Set方式注入(重点)

依赖注入:分成两部分来理解
依赖:依赖spring容器来创建
注入:bean对象中的所有属性,由容器来注入

环境搭建

复杂对象:

package com.mao.pojo;

import lombok.Data;

@Data
public class Address {

    private String address;

}

真实测试对象:

package com.mao.pojo;


import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
public class Student {

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

beans.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="stu1" class="com.mao.pojo.Student">
        <property name="name" value="童小卿"></property>
    </bean>
</beans>

测试类:

package com.mao.test;

import com.mao.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class DiTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student stu1 = (Student) context.getBean("stu1");
        System.out.println(stu1.getName());
    }
}

DI完整实战

beans.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="address" class="com.mao.pojo.Address">
        <property name="address" value="坎墩大昌车业"></property>
    </bean> 
    <bean id="stu1" class="com.mao.pojo.Student">
        <property name="name" value="童小卿"></property>
        <property name="address" ref="address"></property>
        <property name="books">
            <array>
                <value>三国演义</value>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>西游记</value>
            </array>
        </property>
        <property name="games">
            <set>
                <value>LoL</value>
                <value>王者荣耀</value>
                <value>刺激战场</value>
            </set>
        </property>
        <property name="card">
            <map>
                <entry key="身份证" value="33028219951115343X"></entry>
                <entry key="银行卡" value="622384218312731357321"></entry>
            </map>
        </property>
        <property name="hobbys">
            <list>
                <value></value>
                <value></value>
                <value>rap</value>
            </list>
        </property>
        <property name="wife">
            <null/>
        </property>
        <property name="info">
            <props>
                <prop key="身高">185cm</prop>
                <prop key="体重">90KG</prop>
                <prop key="发型">自然卷</prop>
            </props>
        </property>
    </bean>
</beans>

输出结果:
在这里插入图片描述

Bean的作用域

Scope就是作用域,可以在<bean>标签中去设置,其中singleton是单例模式,表示单例,spring默认是单例的。prototype是原型模式,就是拷贝一个新对象,具体可以看我写的设计模式。另外request,session,application等只能在web应用中使用。

spring的自动装配

  • 自动装配是spring满足bean依赖的一种方式。
  • Spring会在上下文中自动寻找,并自动给bean装配属性

在spring中有3中装配方式:

  1. 在xml中显示地配置
  2. 在java中显示配置
  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">
    <bean id="cat" class="com.mao.pojo.Cat"></bean>
    <bean id="dog" class="com.mao.pojo.Dog"></bean>

    <bean id="person" class="com.mao.pojo.Person" autowire="byName">

    </bean>
</beans>

ByName

上述代码中autowire="byName"就是自动在容器上下文中去寻找和自己set方法后面的值相对应的beanid对应的对象。因此当我们使用id为cat和dog的时候我们可以成功注入,但是当把dog改成dog111的时候就报空指针了:
在这里插入图片描述

ByType

会在容器上下文中寻找和想要注入属性同一类型的数据,但是必须保证只有一个该类的bean,否则会报错。

使用注解实现自动装配

使用注解须知:

  1. 导入约束
<?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
       http://www.springframework.org/schema/context/spring-context.xsd">

就是xmlns:context这段以及在约束中添加的内容。
2. 配置注解的支持(beans.xml)

<context:annotation-config/>

该注解非常重要,如果不用的话就无法使用注解。

@Autowired

直接在属性上使用即可!也可以在set方法上使用
使用@Autowired我们可以不用编写set方法了,前提是你的ioc容器中存在自动装配的属性,且符合byName的名字,如果你想要想要获得指定id的bean,就可以在@Autowired下再使用一个@Qualifiar(value=“想要指定的id”);这样就可以了。

注意:如果使用@Autowired找不到bean就会报错,你可以使用@Autowired(required=false)来实现允许bean为null的情况。

@Resource

默认通过ByName,如果找不到则使用byType,可以使用@Resource(name=“bean的id”)来获取指定的bean。

@Autowired和@Resource的区别

  • 都可以放在属性上用来自动装配
  • @Autowired通过ByType的方式实现,而且必须要求这个对象存在【常用】
  • @Resource默认ByName,如果找不到则ByName。两个都找不到就报错

注意:在spring4之后,想通过注解开发,必须导入aop的包。

注解扫描开启

<!-- 指定要扫描的包,这个包下的注解就会生效。@Bean @Compoment @Controller @Service之类 -->
    <context:component-scan base-package="com.mao.pojo"></context:component-scan>
    <!-- 注解驱动,有了该配置就可以使用@Autowired @Resource等注解 -->
    <context:annotation-config/>

使用注解实战

  1. 使用@Compoment
 package com.mao.pojo;

import org.springframework.stereotype.Component;


@Component
public class User {
    public String name = "童胖";
}

使用该注解后就相当于在xml中配置了User的一个类,且会把“童胖”自动注入到其中,然而除了该方法外还有另外的注入方式:

  1. 属性的注入方式
@Component
public class User {
	@Value("童胖")//相当于<property name="name" value="童胖"></property>的配置
    private String name ;//成员变量没赋值默认为null

	@Value("童胖")//除了上述方式外,该方式也等价于上面的方式
	public String getName(){
		return name;
	}
}
  1. 衍生的注解
    相同的功能但是为了适应MVC开发,衍生了三个注解:
  • dao层:@Resposity
  • service层:@Service
  • controller层:@Controller
  1. 其他注解
    @Scope相当于bean中的scope就是指定作用域的
  2. 小结
    xml与注解:
    • xml更加万能,适用于任何场合!维护简单方便
    • 注解不是自己的类使用不了,维护相对复杂
      最佳实践:配置用来管理bean,注解完成属性的注入。

使用Java来配置spring

完全不使用xml,用纯java来配置spring。
在spring之后推荐使用该方式来配置了。

package com.mao.config;

import com.mao.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan("com.mao.pojo")//包扫描
@Import(MaoConfig2.class)//相当于xml中的<import>
//该配置文件就相当于以前的application.xml
public class MaoConfig {

    @Bean
    //注册一个bean,就相当于我们之前写的一个bean标签
    //这个方法的名字就相当于bean标签中的id属性(这里用了user)
    //这个方法的返回值就相当于bean标签中的class属性
    public User user(){
        return new User();
    }
}

//需要注意的是@Configuration本身也是一个@Compoment,而想通过配置实现就需要实现的类是ApplicationContext context = new AnnotationConfigApplicationContext(MaoConfig.class);

发布了37 篇原创文章 · 获赞 10 · 访问量 740

猜你喜欢

转载自blog.csdn.net/weixin_41746577/article/details/103475211