spring-ioc

Spring框架-IOC

依赖:class A中使用了class B的方法或者属性等等类信息,叫做A依赖B

Spring框架:

spring-ioc

Data Access/Integration:数据访问/集成

Instrumentation:JVM代理

Messaging:消息发送

AOP、Aspects:面向切面编程

Core Container:核心容器

Test:测试

Spring框架的优点:

1、轻量

2、针对接口编程,解耦合

3、支持AOP编程

4、方便集成其他框架

IOC:控制反转

控制:对象的创建和维护 ( 创建对象 对象的属性和赋值 对象之间关系的管理)

反转:

正转:开发人员在代码中使用new创建新对象,开发人员主动控制对象

IOC:控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护

DI(依赖注入):实现IOC的一种方式,是指在程序运行过程中,如果需要调用另一个对象的协助,无需在代码中创建被调用者,而是依赖于外部容器,由容器创建后传递给程序。

Spring框架使用DI实现IOC:Spring框架相当于一个大的容器,负责创建和维护java对象,这些java对象被称为Bean。Spring容器使用DI管理这些Bean之间的依赖关系。

DI实现的两种方式:

1、在Spring配置文件中使用标签和属性完成(基于XML)

2、使用Spring中的注解完成属性的赋值(基于注解)

java中创建对象的几种方式:

1、使用new关键字2、反射3、clone方法4、反序列化

Java Bean:

1、类是公共的2、有一个无参的构造器(public)3、有和属性对应的get和set方法(public)

Java Bean的实例化过程:

spring-ioc

Arare接口:

Spring的依赖注入最大亮点就是所有的Bean对Spring容器的存在是没有意识的。但是在实际项目中,我们有时不可避免的要用到Spring容器本身提供的资源,这时候要让 Bean主动意识到Spring容器的存在,才能调用Spring所提供的资源,这就是Spring的Aware接口,Aware接口是个标记接口,标记这一类接口是用来“感知”属性的,Aware的众多子接口则是表征了具体要“感知”什么属性。例如BeanNameAware接口用于“感知”自己的名称,ApplicationContextAware接口用于“感知”自己所处的上下文。其实Spring的Aware接口是Spring设计为框架内部使用的,在大多数情况下,我们不需要使用任何Aware接口,除非我们真的需要它们,实现了这些接口会使应用层代码耦合到Spring框架代码中。

Java Bean的几个属性:

id:对象的自定义名称,spring容器通过这个id找到Bean
class:类的全限定名称(不可以是接口)
scope:作用域
Constructor arguments:调用构造函数
Properties:调用set方法
Autowiring mode:自动注入方式
lazy-initialization mode

Initialization/destruction method:

Bean的作用域

spring-ioc

应用(application) 限定一个Bean的作用域为ServletContext的生命周期。同样,只有基于web的Spring ApplicationContext可用

一般来说request session globalSession这三种作用域只存在于web框架中

Bean的初始化和销毁:

spring-ioc

public class MyBean implements InitializingBean , DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("即将被销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("即将被创建");
    }

也可以配置全局初始化销毁函数:

<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"
default-destroy-method="com.geng.domain.MyBean.destroy"
default-init-method="com.geng.domain.MyBean.afterPropertiesSet">
Bean的自动注入(主要是简化引用数据类型的赋值)

spring-ioc

可以在xmls中添加default-autowire=“byName”

可以分为两种:

1、设值注入:set方法

 <bean id="firstBean2" class="com.geng.domain.MyBean">
     <property name="age" value="1"/>
     <property name="password" value="123"></property>
     <property name="name" value="geng"/>
 </bean>
<bean id="myService1" class="com.geng.service.impl.MyServiceImpl">
    <property name="name" value="lala"/>
    <property name="age" value="22"/>
    <property name="myBean" ref="firstBean1"/>
</bean>

2、构造注入:有参构造函数

<bean id="firstBean1" class="com.geng.domain.MyBean">
    <constructor-arg name="age" value="2"/>
    <constructor-arg name="name" value="peng"/>
    <constructor-arg name="password" value="456"/>
</bean>

<bean id="myService2" class="com.geng.service.impl.MyServiceImpl">
    <constructor-arg name="name" value="lala"/>
    <constructor-arg name="age" value="22"/>
    <constructor-arg name="myBean" ref="firstBean2"/>
    //还有一个index属性,标明是构造器的第几个参数,但是一般不使用
<dependencies>
    //Spring核心依赖
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.16.RELEASE</version>
    </dependency>
    //测试依赖
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>
</dependencies>
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>

    <!--指定jdk版本-->
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
<bean id="firstBean2" class="com.geng.domain.MyBean">
    <property name="age" value="1"/>
    <property name="password" value="123"></property>
    <property name="name" value="geng"/>
</bean>

@Test
public void test01(){
    ApplicationContext applicationContext=(ApplicationContext) new ClassPathXmlApplicationContext("ApplicationContext.xml");
    int num=applicationContext.getBeanDefinitionCount();
    String applicationName = applicationContext.getApplicationName();
    String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
    System.out.println(num+applicationName);
    for(String str:beanDefinitionNames){
        MyBean myBean=(MyBean)applicationContext.getBean(str);
        System.out.println(myBean.toString());
    }
}
为项目指定多个Spring配置文件

​ 在实际应用中,随着应用规模的增加,系统的Bean也会大量增加,导致配置文件变得非常庞大,为了提高配置文件的可读性与可维护性,也已将Spring配置文件分解为多个配置文件

通过引入。可以使用通配符,但是要注意通配符肯定是不可以匹配到父配置文件,以避免造成递归引入。

基于注解的DI

需要了解的注解:

1、@Component 表示创建一个Bean

2、@Repository 表示创建一个Dao层的Bean

3、@Service 表示创建一个Service层的Bean

4、@Value 表示自动注入一个基本数据类型

位置:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

5、@Autowired 表示自动注入引用数据类型

spring框架提供,支持ByType和ByName自动注入,默认是ByType,属性required,默认为true,

此时当引用数据类型赋值出现错误,会进行报错并且终止程序运行;如果为false,不会报错,会跳过此次赋值(null)。如果要使用ByName进行自动注入,要使用@Qualifier(value=“ ”)注解

位置:
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
注意:

使用@Value注解和@Autowired注解的时候一定要编写无参构造和带参构造,类的构造函数必须写全,要不也会报错。

@Component("myBean1")
public class MyBean {
    @Value("geng")
    private String name;
    private int age;
    public MyBean() {
    }
    public MyBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Value("12")
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "MyBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
@Service
public class MyService {
    @Qualifier(value = "myBean1")
    @Autowired
    private MyBean myBean;

    public void tString(){
        System.out.println(myBean.toString());
    }
}

6、@Controller 表示一个Controller层的Bean

7、@Resource 表示自动注入引用数据类型

这个注解是来自JDK,默认是先使用byName自动注入,如果失败再使用byType(如果你只想使用byName这一种方式,可以使用name属性进行指定)

位置:
@Target({TYPE, FIELD, METHOD})
组件扫描器:
<!--第一种方式,使用多次组件扫描器,每一次指定一个包-->
<context:component-scan base-package="com.geng.ba1"/>
<context:component-scan base-package="com.geng.ba2"/>
<!--第二种方式,使用分隔符;或者,分隔多个包名-->
<context:component-scan base-package="com.geng.ba2;com.geng.ba1"/>
<!--第三种方式 指定父包-->
<context:component-scan base-package="com.geng"/>

也可以自定义扫描:

Spring扫描自定义注解的实现 - 祝涛的个人空间 - OSCHINA - 中文开源技术交流社区

spring-ioc

上一篇:程序猿多个对象的友好管理方式IOC容器


下一篇:腾讯Redis压轴笔记,springboot面试