Spring

Posted bobstudyjava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring相关的知识,希望对你有一定的参考价值。

1.简介

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

2.组成

-七大模块

3.IOC理论推导

在没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后对象的创建转移给第三方。本质就是创建对象的控制权转移了。

4.IOC创建对象

在配置文件加载的时候,容器中管理的对象就已经初始化了

#默认使用无参构造函数
<!--    使用spring来创建对象,在spring中对象被称为bean-->
    <bean id="hello" class="com.kuang.pojo.Hello">
<! bean 相当于 new hello ,id相当于变量名,class是全限定名;name是具体的属性名,value是给属性赋值;ref是指向类对象-->
        <property name="name" value="Spring"/>
    </bean>

#有参构造,constructor-arg,构造函数的参数
    <bean id="hello" class="com.kuang.pojo.Hello">
        <constructor-arg name="name" value="spring"/>
    </bean>

<import> 可以合并所有的beans.xml文件

5.依赖注入

依赖:bean对象的创建依赖于容器
注入:bean对象的所有属性由容器注入

5.1构造器注入

见 4 IOC创建对象

5.2set注入

array :数组注入
list :list注入
map :map注入
set :set注入
null :null值注入

6.bean的作用域

单例模式,每次从容器中get的时候都是同一个:

    <bean id="hello" class="com.kuang.pojo.Hello" scope="singleton">
        <constructor-arg name="name" value="bwp"/>
    </bean>

原型模式,每次从容器中get的时候都会产生新对象:

    <bean id="hello" class="com.kuang.pojo.Hello" scope="prototype">
        <constructor-arg name="name" value="bwp"/>
    </bean>

7.bean的自动装配

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

1.xml中的显示配置
2.在java中的显示配置
3.隐式的自动装配

#byName会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid,需要保证beanid唯一
#byType会自动在容器上下文中查找,和自己对象set属性类型相同的beanid,需要保证所有bean的class唯一
    <bean id="hello" class="com.kuang.pojo.Hello"  autowire="byName">
        <constructor-arg name="name" value="bwp"/>
    </bean>

7.2 使用注解实现自动装配
#导入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/beans/spring-context.xsd">
<!--    配置注解的支持-->
    <context:annotation-config/>
    <context:component-scan base-package="com.kuang.pojo"/>
 </beans>

如果自动装配无法通过一个注解完成的时候@Autowired(通过ByType实现),可以加上@Qualifier去配合使用,指定一个唯一的bean对象注入。

8、使用注解开发

<?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
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

<!--    指定要扫描的包-->
    <context:component-scan base-package="com.kuang.pojo"/>
    <!--    注解的支持-->
    <context:annotation-config/>
</beans>

创建对象:
@Component:相当于,有几个衍生注解,这四个注解功能一样,将某个类装配到spring容器中进行托管

  • dao [@Repository]
  • service [@Service]
  • controller[@Controller]

注入值:
@Value("xxx") 相当于给属性赋值

作用域:
@Scope("singleton")

XML和注解的最佳实践:
xml用管理bean,注解负责属性的注入

9、完全使用注解

用配置类取代xml配置文件

package com.kuang.config;

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

@Configuration
@ComponentScan("com.kuang.pojo")
//该注解是一个配置,类似之前的beans.xml
public class MyConfig 

//    注册一个bean,类似xml中的bean标签
//    方法的名字类似xml中的id
//    方法的返回值类似xml中的class属性
    @Bean
    public User getUser()
        return new User();
    


10.代理模式

优点:代理模式使得真实角色的操作更加纯粹,不用关注公共业务,交给代理角色,实现了业务的分工。不改变原有代码的情况下,业务扩展方便管理;
缺点:一个真实角色会产生一个代理角色,方便集中管理

10.1静态代理
#接口
package com.kuang;

public interface UserService 
        public void add();
        public void del();
        public void update();
        public void query();


#实现接口
package com.kuang;

public class UserServiceImpl implements UserService
    @Override
    public void add() 
        System.out.println("增加了一个用户");
    

    @Override
    public void del() 
        System.out.println("删除了一个用户");
    

    @Override
    public void update() 
        System.out.println("修改了一个用户");
    

    @Override
    public void query() 
        System.out.println("查询了一个用户");
    


#添加日志,通过静态代理实现
package com.kuang;

public class UserServiceProxy implements UserService
    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) 
        this.userService = userService;
    

    @Override
    public void add() 
        log("add");
        userService.add();
    

    @Override
    public void del() 
        log("del");
        userService.del();
    

    @Override
    public void update() 
        log("update");
        userService.update();
    

    @Override
    public void query() 
        log("query");
        userService.query();
    

    public void log(String msg)
        System.out.println(msg);
    


#客户端调用
package com.kuang;

public class Client 
    public static void main(String[] args) 
        UserServiceImpl userService=new UserServiceImpl();
        UserServiceProxy userServiceProxy=new UserServiceProxy();
        userServiceProxy.setUserService(userService);
        userServiceProxy.add();
    


10.2动态代理

动态代理的代理类是动态生成的,不是直接写好的
动态代理分为俩大类:基于接口的,基于类的
InvocationHandler:由代理实例的调用处理程序实现的接口
Proxy:提供创建动态代理的实例和方法
一个动态代理类可以代理多个类,只要实现了同一个接口即可

#接口
package com.kuang.demo2;

public interface Rent 
    public void rent();


#实现接口
package com.kuang.demo2;

public class Host implements Rent
    @Override
    public void rent() 
        System.out.println("房东要出租房子");
    


#代理
package com.kuang.demo2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationHandler implements InvocationHandler 

//    被代理的接口
    private Rent rent;

    public void setRent(Rent rent) 
        this.rent = rent;
    

    //    生成代理类
    public Object getProxy()
        return  Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);

    


//    处理代理实例,返回处理结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        //动态代理的本质就是反射
        Object result = method.invoke(rent,args);
        return result;
    


#客户端调用
package com.kuang.demo2;

public class Client 
    public static void main(String[] args) 
        //真实角色
        Host host=new Host();

//        代理角色
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setRent(host);
        Rent proxy = (Rent) pih.getProxy();
        proxy.rent();


    


11.AOP

AOP(Aspect Oriented Programming):面向切面编程,通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部门的耦合度降低,提高程序的可用性,同时提高开发效率。在不影响原来业务的情况下,实现动态增强。

  • 使用spring接口实现aop
  • 使用注解实现aop

应用场景:
1.日志
2.安全
3.事务

12.mybatis-spring

将mybatis代码无缝整合到spring中,它将允许mybatis参与到spring的事务管理之中

以上是关于Spring的主要内容,如果未能解决你的问题,请参考以下文章

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring JDBC