关于Spring知识点的小结

知识点一

  • 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 是当前类的类名。首字母小写。
  • @Autowired@Qualifier@Resource
  • @Value作用:
    注入基本数据类型和 String 类型数据的
    属性:
    value:用于指定值
  • @Scope作用:
    指定 bean 的作用范围。
    属性:
    value:指定范围的值。
    取值:singleton prototype request session globalsession
  • 注解的优势:
    配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
    XML  的优势:
    修改时,不用改源码。不涉及重新编译和部署。
    Spring  管理 Bean  方式的比较:

知识点五

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实现事物控制

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值