欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Spring知识点的小结

程序员文章站 2022-03-14 10:29:07
...

知识点一

  • Spring致力于提供一种方式去管理下项目中的所有对象,塔式分层的javase/ee应用(一站式)full-stack的轻量级开源框架。为什么这么说呢?主要是因为①作用于各个层,②整合第三方优秀框架.
  • 接下来,说下spring的体系结构.:五部分包括核心容器.aop,text,web,dao等.
  • spring IOC的底层原理就是:工厂设计模式+配置文件+反射机制来解决代码与代码(类与类)之间的耦合.
  • IOC 控制反转:本该由程序创建new 创建的对象,现在把权力给了spring,通过DI依赖注入,解决了对象与对象之间的依赖关系.

知识点二

创建bean的三种方式:

第一步:导约束

<?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的三种方式 -->
    <!-- 第一种方式:使用默认构造函数创建。
            在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
            采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
    -->

    <!-- 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
    <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
    -->

    <!-- 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
    <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>
    -->
<!-- bean对象的生命周期
            单例对象
                出生:当容器创建时对象出生
                活着:只要容器还在,对象一直活着
                死亡:容器销毁,对象消亡
                总结:单例对象的生命周期和容器相同
            多例对象
                出生:当我们使用对象时spring框架为我们创建
                活着:对象只要是在使用过程中就一直活着。
                死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
     -->


</beans>
  • 如果是自己写的类,使用无参构造
  • 如过是其他jar包,没有提供无参构造,需要模拟一个工厂类,工厂中普通成员方法创建对象
  • 工厂中静态方法创建对象

知识点三

DI:依赖注入

依赖注入解决对象与对象之间的依赖关系

  • 类中的构造函数,类中需要提供一个对应参数列表的构造函数
  • setter,类中提供需要注入成员的 set 方法
  • 注解

知识点四

基于注解的 IOC  配置

  1. 拷贝jar包
  2. 导入约束
基于注解整合时,导入约束时需要多导入一个 context 名称空间下的约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 告知 spring 创建容器时要扫描的包 -->
...
</beans>

 

常用一些注解

  • @Component作用:(@Controller @Service @Repository)
    把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
    属性:
    value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。
  • @aaa@qq.com@Resource
  • @Value作用:
    注入基本数据类型和 String 类型数据的
    属性:
    value:用于指定值
  • @Scope作用:
    指定 bean 的作用范围。
    属性:
    value:指定范围的值。
    取值:singleton prototype request session globalsession
  • 注解的优势:
    配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
    XML  的优势:
    修改时,不用改源码。不涉及重新编译和部署。
    Spring  管理 Bean  方式的比较:
  • 关于Spring知识点的小结

知识点五

Spring AOP

讲AOP之前,先回忆下servlet

  • servlet的生命周期,servlet在Tomact服务器中是一个单实例,多线程的对象.①我们部署的项目一发布当第一个用户访问的时候,就会创建serlet,其他用户再次访问,就不会再创建了,创建时会调用init方法.②当有用户访问,servlet都会开启一个子线程去调用service方法.③正常关闭,会调用destroy方法销毁servlet.接下来会用ThreadLocal<Connection>,底层是一个map,让key保存当前线程,value保存connnectioon,能起到一个线程和连接引用的关系,从而保证我们的连接唯一.(每个方法都要被事物管理)

我们说sevrlet是一个小程序,服务器一启动,xml文件加载,Tomact--运行在jvm中,servlet运行在Tomact中!

  • 以上会造成我们的事物代码和service代码的耦合,所有AOP解决的就是业务逻辑和业务逻辑的耦合,底层使用的是动态代理.

动态代理两种方式:

jdk动态代理对象和原始对象是兄弟关系,只能针对接口产生代理,也就是说代理的对象必须实现一个接口.

/**
 * 用于创建Service的代理对象的工厂
 */
public class BeanFactory {

    private IAccountService accountService;

    private TransactionManager txManager;

    public void setTxManager(TransactionManager txManager) {
        this.txManager = txManager;
    }


    public final void setAccountService(IAccountService accountService) {
        this.accountService = accountService;
    }

    /**
     * 获取Service代理对象
     * @return
     */
    public IAccountService getAccountService() {
        return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(),
                accountService.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 添加事务的支持
                     *
                     * @param proxy
                     * @param method
                     * @param args
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        if("test".equals(method.getName())){
                            return method.invoke(accountService,args);
                        }

                        Object rtValue = null;
                        try {
                            //1.开启事务
                            txManager.beginTransaction();
                            //2.执行操作
                            rtValue = method.invoke(accountService, args);
                            //3.提交事务
                            txManager.commit();
                            //4.返回结果
                            return rtValue;
                        } catch (Exception e) {
                            //5.回滚操作
                            txManager.rollback();
                            throw new RuntimeException(e);
                        } finally {
                            //6.释放连接
                            txManager.release();
                        }
                    }
                });

    }
}

CGLIB代理的对象,不管目标类有没有实现接口,产生的代理对象和原始对象是子父类关系,原始类是不能被final修饰.

/**
 * 模拟一个消费者
 */
public class Client {

    public static void main(String[] args) {
        final Producer producer = new Producer();

        /**
         * 动态代理:
         *  特点:字节码随用随创建,随用随加载
         *  作用:不修改源码的基础上对方法增强
         *  分类:
         *      基于接口的动态代理
         *      基于子类的动态代理
         *  基于子类的动态代理:
         *      涉及的类:Enhancer
         *      提供者:第三方cglib库
         *  如何创建代理对象:
         *      使用Enhancer类中的create方法
         *  创建代理对象的要求:
         *      被代理类不能是最终类
         *  create方法的参数:
         *      Class:字节码
         *          它是用于指定被代理对象的字节码。
         *
         *      Callback:用于提供增强的代码
         *          它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
         *          此接口的实现类都是谁用谁写。
         *          我们一般写的都是该接口的子接口实现类:MethodInterceptor
         */
        Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
            /**
             * 执行北地阿里对象的任何方法都会经过该方法
             * @param proxy
             * @param method
             * @param args
             *    以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
             * @param methodProxy :当前执行方法的代理对象
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //提供增强的代码
                Object returnValue = null;

                //1.获取方法执行的参数
                Float money = (Float)args[0];
                //2.判断当前方法是不是销售
                if("saleProduct".equals(method.getName())) {
                    returnValue = method.invoke(producer, money*0.8f);
                }
                return returnValue;
            }
        });
        cglibProducer.saleProduct(12000f);
    }
}

知识点6

配置AOP 的两种方式 xml和注解

知识点7

spring实现事物控制

 

 

 

 

 

 

相关标签: 框架