Spring 讲解(一 )

1、如何理解 Spring 框架

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

因为以前写代码的时候,在使用类对象的时候,经常需要实例化创建(new 出来)很多对象,有时候只需要实例化一次对象即可(不管这个对象是 service 或者 dao),让这个对象去做该做的事情。

而Spring框架就是管理这些对象的,让 Spring 容器装配管理这些对象,程序猿需要时再取出来使用,让对象的创建和使用更加方便。

【Bean其实就是一个new好的对象】

2、使用 Spring 的好处

  • 方便解耦,简化开发

    Spring就是一个大工厂,专门负责生成Bean,可以将所有对象创建和依赖关系维护由Spring管理。

  • AOP编程的支持

    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。

  • 声明式事务的支持

    只需要通过配置就可以完成对事务的管理,而无需手动编程。

  • 方便程序的测试

    Spring对Junit4支持,可以通过注解方便的测试Spring程序。

  • 方便集成各种优秀框架

    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的支持。

  • 降低JavaEE API的使用难度

    对JavaEE开发中一些难用的API(JDBC、JavaMail、远程调webservice用等),都提供了封装,使这些API应用难度大大降低。

3、说了这么多,是骡子是马,拉出来溜溜(案例演示)

  • 创建接口和实现类

    public interface UserService {
        void add();
    }
    
    =============================================================================
    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("创建用户....");
        }
    }
    
  • 不使用 Spring 调用对象方法

    public class ServiceTest {
        public static void main(String[] args) {
            UserService userService=new UserServiceImpl();
            userService.add();
        }
    }
    

    控制台打印结果日志:创建用户....

  • 使用 Spring 管理对象

    首先需要创建 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 【对象】-->
                <bean id="userService" class="com.example.demo.service.impl.UserServiceImpl"/>
    </beans>
    
     public class ServiceTest {
         public static void main(String[] args) {
    
             //1.加载beans.xml 这个spring的配置文件,内部就会创建对象
             ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    
             //2.从spring容器获取 userSerivce对象
             UserService userSerivce1 = (UserService) context.getBean("userService");
             userSerivce1.add();
    
             UserService userSerivce2 = (UserService) context.getBean("userService");
             userSerivce2.add();
    
             System.out.println(userSerivce1);
             System.out.println(userSerivce2);
         }
     }
    

控制台打印结果日志如下:

创建用户....

创建用户....

com.example.demo.service.impl.UserServiceImpl@3b088d51
com.example.demo.service.impl.UserServiceImpl@3b088d51

可以看出是Spring在启动加载配置文件 bean.xml 的时候,会在容器中创建好这个对象,需要使用的时候直接获取就可以。

相比以前每次都要 new(频繁 new 对象的过程对程序开销很大) 一个对象。交给 Spring 容器后这个对象只会创建一次,所以打印的地址值是一样的。

2、对 Spring 中 IOC 和 DI 讲解

  • IoC 反转控制

    就是将原本在程序中手动创建 UserService 对象的控制权,交由 Spring 框架管理。简单说就是创建 UserService 对象控制权被反转到了 Spring 框架。

  • DI 依赖注入

    在 Spring 框架负责创建 Bean 对象时,动态的将依赖对象注入到 Bean 组件。

  • 对依赖注入(DI)案例演示

    public class UserServiceImpl implements UserService {
    
        private String name;
      
      // 可以注释掉 getName 方法
        public String getName() {return name;}
    
        // setName 方法不可以注释掉
        public void setName(String name) {this.name = name;}
    
        @Override
        public void add() {
            System.out.println("创建用户...." + name);
        }
    }
    
     <?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 【对象】-->
                <bean id="userService" class="com.example.demo.service.impl.UserServiceImpl">
                    <!-- 依赖注入数据,调用属性的set方法 -->
                    <property name="name" value="zhangsan"></property>
                </bean>
            </beans>
    

    运行原来的 Main 方法,控制台打印结果日志如下:

    创建用户....zhangsan

    创建用户....zhangsan

    com.example.demo.service.impl.UserServiceImpl@7a187f14
    com.example.demo.service.impl.UserServiceImpl@7a187f14

  • 重点

    UserServiceImpl 中如果注释掉 getName ,程序不出错。如果注释掉 setName 方法,则会报错如下所示,至于报错的原因,请看下一篇讲解。

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in class path resource [beans.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'name' of bean class [com.example.demo.service.impl.UserServiceImpl]: Bean property 'name' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1718)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1433)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
      at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
      at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
      at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
      at com.example.demo.testservice.ServiceTest.main(ServiceTest.java:16)
    Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'name' of bean class [com.example.demo.service.impl.UserServiceImpl]: Bean property 'name' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
      at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:243)
      at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426)
      at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278)
      at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266)
      at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97)
      at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1714)
      ... 13 more
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容