spring入门

介绍

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

ioc基础

原始的项目写法-接口和实现

public interface UserDao {
    void getUer();
}
public class UserDaoImpl implements UserDao {
    public void getUer() {
        System.out.println("获取用户数据");
    }
}

service

public interface Iuser {
    public void getUser();
}
public class IUserService implements Iuser {
    private UserDao userDao = new UserDaoImpl();

    public void getUser() {
        userDao.getUer();
    }
}

如果想要增加不同的实现,需要修改新的实现

public class UserDaoMysql implements UserDao{
    public void getUer() {
        System.out.println("msyql 获取用户信息");
    }
}

service层

public class IUserService implements Iuser {
//    private UserDao userDao = new UserDaoImpl();
    private UserDao userDao = new UserDaoMysql();

    public void getUser() {
        userDao.getUer();
    }
}

那么我们要使用Oracle , 又需要去service实现类里面修改对应的实现 . 假设我们的这种需求非常大 , 这种方式就根本不适用了, 甚至反人类对吧 , 每次变动 , 都需要修改大量代码 . 这种设计的耦合性太高了, 牵一发而动全身 .

那我们如何去解决呢 ?

可以用set方法,在调用的时候在把属性set进来!

public class IUserServiceSet implements Iuser {
    private UserDao userDao;

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

    public void getUser() {
        userDao.getUer();
    }
}

在调用的时候,根据业务set dao

    public void user() {
//        Iuser iuser = new IUserService();
//        iuser.getUser();
        Iuser iuser =new IUserServiceSet();
        ((IUserServiceSet) iuser).setUserDao(new UserDaoOracle());
        iuser.getUser();
        //需要用到MySQL
        ((IUserServiceSet) iuser).setUserDao(new UserDaoMysql());
        iuser.getUser();
    }

以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .

这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 !

IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
在这里插入图片描述
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

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

HelloSpring -入门例子

Hello 实体

public class Hello {
    private String name;

    public Hello() {
    }

    public Hello(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show() {
        System.out.println("hello:" + name);
    }
}

resource 目录下新建bean.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="hello" class="com.songyang.service.Hello">
        <property name="name" value="songyang"/>
    </bean>

</beans>

测试

    @Test
    public void hello() {
        //解析beans.xml文件 , 生成管理相应的Bean对象
        ClassPathXmlApplicationContext context  = new ClassPathXmlApplicationContext("bean.xml");
        //getBean : 参数即为spring配置文件中bean的id .
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
    }

属性注入的本质是通过set方法进行注入,如果将实体中的set方法去掉,将不能完成注入!!!!

Hello 对象是谁创建的 ? 【hello 对象是由Spring创建的 Hello 对象的属性是怎么设置的 ? hello 对象的属性是由Spring容器设置的
这个过程就叫控制反转 :

  • 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
  • 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
    依赖注入 : 就是利用set方法来进行注入的.

IOC是一种编程思想,由主动的编程变成被动的接收

可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .

现在对原来的代码进行修改
在bean.xml中配置类

    <bean id="UserDaoImpl" class="com.songyang.dao.UserDaoImpl"></bean>
    <bean id="UserDaoMysql" class="com.songyang.dao.UserDaoMysql"></bean>
    <bean id="UserDaoOracle" class="com.songyang.dao.UserDaoOracle"></bean>

    <bean id="IUserServiceSet" class="com.songyang.service.IUserServiceSet">
        <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写-->
        <!--引用另外一个bean , 不是用value 而是用 ref-->
        <property name="userDao" ref="UserDaoOracle"></property>
    </bean>

注意!这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写!

测试方法

    @Test
    public void hello() {
        //解析beans.xml文件 , 生成管理相应的Bean对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        //getBean : 参数即为spring配置文件中bean的id .
//        Hello hello = (Hello) context.getBean("hello");
//        hello.show();
        IUserServiceSet iUserServiceSet = (IUserServiceSet) context.getBean("IUserServiceSet");
        iUserServiceSet.getUserInfo();
    }

到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !

IOC创建对象的方式

无参构造器创建

public class Hello {
    private String name;

    public Hello() {
        System.out.println("这是hello的无参构造函数!!!!");
    }
    
    <bean id="hello" class="com.songyang.service.Hello">
        <property name="name" value="songyang"/>
    </bean>

实现

    @Test
    public void hello() {
        //解析beans.xml文件 , 生成管理相应的Bean对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        //getBean : 参数即为spring配置文件中bean的id .
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
//        IUserServiceSet iUserServiceSet = (IUserServiceSet) context.getBean("IUserServiceSet");
//        iUserServiceSet.getUserInfo();
    }
结果:
这是hello的无参构造函数!!!!
hello:songyang

<property 标签默认就是无参构造器创建bean

有参构造函数创建对象

<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- index指构造方法 , 下标从0开始 -->
   <constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- name指参数名 -->
   <constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置(不推荐使用) -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>

别名

<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>

<!--bean就是java对象,Spring创建和管理-->

<!--
   id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
   如果配置id,又配置了name,那么name是别名
   name可以设置多个别名,可以用逗号,分号,空格隔开
   如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;

class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
   <property name="name" value="Spring"/>
</bean>

import

<import resource="{path}/beans.xml"/>

bean作用域

在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象 .

在这里插入图片描述

 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

Bean 的自动装配

实际项目中都是用注解装配

1、在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

2、开启属性注解支持!

<context:annotation-config/>

需要导入 spring-aop的包!

测试
1、实体中set方法去掉 用@autowird

public class User {
   @Autowired
   private Cat cat;
   @Autowired
   private Dog dog;
   private String str;

   public Cat getCat() {
       return cat;
  }
   public Dog getDog() {
       return dog;
  }
   public String getStr() {
       return str;
  }
}

2、配置文件中的bean

<context:annotation-config/>

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

注意要开启注解配置 context:annotation-config/

使用注解开发

1、配置文件中引入context约束

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

</beans>

2、配置扫描哪些包下的注解

<context:component-scan base-package="com.kuang.pojo"/>

3、编写实体类 加上@component 注解

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
   public String name = "秦疆";
}

@Component(“user”) 默认是类名小写

4、属性注入
4.1 属性上直接注入

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
   @Value("秦疆")
   // 相当于配置文件中 <property name="name" value="秦疆"/>
   public String name;
}

4.2 set方法上注入

@Component("user")
public class User {

   public String name;

   @Value("秦疆")
   public void setName(String name) {
       this.name = name;
  }
}

小结
XML与注解比较

XML可以适用任何场景 ,结构清晰,维护方便
注解不是自己提供的类使用不了,开发简单方便
xml与注解整合开发 :推荐最佳实践

xml管理Bean
注解完成属性注入
使用过程中, 可以不用扫描,扫描是为了类上的注解
context:annotation-config/
作用:

进行注解驱动注册,从而使注解生效
用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
如果不扫描包,就需要手动配置bean
如果不加注解驱动,则注入的值为null!

使用Java的方式配置spring

1、编写一个实体类,Dog

@Component  //将这个类标注为Spring的一个组件,放到容器中!
public class Dog {
   public String name = "dog";
}

2、新建一个config配置包,编写一个MyConfig配置类

@Configuration  //代表这是一个配置类
public class MyConfig {

   @Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
   public Dog dog(){
       return new Dog();
  }

3、测试

@Test
public void test2(){
   ApplicationContext applicationContext =
           new AnnotationConfigApplicationContext(MyConfig.class);
   Dog dog = (Dog) applicationContext.getBean("dog");
   System.out.println(dog.name);
}

4、成功输出结果!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值