Spring框架 、依赖注入、注解、Spring AOP、Spring IOC

Spring框架:不属于mvc架构的任何一层,不是单纯的代替某一种开发技术
作用:提供容器,进行对象管理

开源的 轻量级的 非侵入式的 控制反转 IOC面向切面 AOP 的容器框架

  • 开源的:免费的
  • 轻量级的:占用空间小
  • 非侵入式的:在使用框架过程中,几乎不需要使用它的API来编码
    程序易于维护,易于扩展

API:定义好的接口,可直接访问,不需要源码

  • 控制反转 IOC:Spring最核心的部分

把程序中对象管理的控制,反转给Spring容器( Spring核心配置文件 )去做处理

举个栗子:高内聚 低耦合

A :B b = new B;b.方法()耦合度
B :C c = new C;c.方法()耦合度
C

  • 面向切面 AOP :面向切面的编程

把程序中要实现的功能进行分类

  1. 横切关注点: (与业务不相关的,比较公共的功能点 日志管理 安全性检查。。。)
  2. 垂直关注点:(系统实现业务功能点 登录 注册 下订单。。。)

IOC:设计思想(对象管理)

尽可能降低程序的耦合度,提高程序的可维护型,可扩展性
  • Spring对IOC思想有比较好的实现
  • 选用Spring框架的IOC来解决程序中对对象管理的问题

AOP:设计思想(解决程序中横切关注点功能实现)

把代码提到某一个类中去实现,在程序运行或者编译期间,把横切关注点的代码加入到业务代码中,提升开发效率,提高代码重用性

Spring框架的体系结构、

  • Spring Core:Spring IOC
  • Spring AOP:面向切面编程
  • Spring ORM:提供持久层框架进行集合的功能
  • Spring DAO:提供与数据库交互的JDBC的过程
  • Spring Web:与Servlet技术进行集成的功能
  • Spring WebMvc:Spring框架的子框架(代替Servlet技术为完成的控制功能的框架)
  • Spring Context:提供企业级开发技术进行集成的功能(发邮件 付款。。。)

搭建Spring工程

  1. 创建普通的java工程
  2. 导入Jar包
  3. 引用Spring配置文件

Spring IOC:单独进行一个对象的管理

Spring在管理对象时,把每一个要管理的独享叫做 bean

bean标签
  • id属性:对象在容器中唯一标识
  • name属性:唯一标识,与id属性同理
  • class属性:要管理的类的全类名
  • scape属性:设定bean的作用域
    • singleton:默认值 单例模式
    • prototype:非单例模式
    • request:创建出的bean的生命周期是一个request范围内
    • session:创建出的bean的生命周期是一个session范围内
  • lazy-init属性:用于设定bean是否延迟初始化
    • false:默认值 非延迟初始化 Spring容器加载过程中就完成对象的构建 推荐使用
    • true:延迟初始化
    <bean  id="first" class="spring.bean.FirstBean"   />

依赖注入( DI ):基于xml文件进行依赖注入

  1. 构造注入
xml文件
    <!-- 构造注入 -->
    <bean id="example" class="Spring.bean.ExampleBean">
//结构属性标签
//constructor-arg:结构--参数
        <constructor-arg>
            <ref bean="first"/>
        </constructor-arg>
        <constructor-arg>
            <ref bean="second"/>
        </constructor-arg>
        
    </bean>
bean.java
public class ExampleBean {
    //构造注入
    private FirstBean f;
    private SecondBean s;
    
    public ExampleBean(FirstBean f,SecondBean s) {
        this.f = f;
        this.s = s;
    }
    
    public void print() {
        System.out.println("ExampleBean的print方法");
        f.test();
        s.run();        
    }
}
Test
        //构造注入
        ExampleBean e = (ExampleBean) app.getBean("example");
        e.print();//ExampleBean的print方法 // FirstBean //SecondBean
  1. 属性注入(setter注入)
xml文件
   <!-- 属性注入 -->
   <bean id="newexample" class="Spring.bean.NewExampleBean">
   <!-- 
       property标签:
       name:与类中类中成员变量的名字相同
       ref:要注入的bean的id
    -->
        <property name="firstBean" ref="first"/>
        <property name="secondBean" ref="second"></property>
   </bean>
   
   <bean id="userDAO" class="Spring.dao.UserDAO"></bean>
   <bean id="userService" class="Spring.service.UserService">
   <property name="dao" ref="userDAO"></property>
       
   </bean>
bean.java
public class NewExampleBean {
    private FirstBean firstBean;
    private SecondBean secondBean;
    
    public void setSecondBean(SecondBean secondBean) {
        this.secondBean = secondBean;
    }

    //set方法
    public void setFirstBean(FirstBean firstBean) {
        this.firstBean = firstBean;
    }

    public void test() {
        System.out.println("NewExampleBean的test方法");
        firstBean.test();
        secondBean.run();
    }

}
Test
        //属性注入
        NewExampleBean ne = (NewExampleBean) app.getBean("newexample");
        ne.test();//NewExampleBean的test方法 //FirstBean //SecondBean
        
        UserService service = (UserService) app.getBean("userService");
        service.register();//UserService的register方法 //UserDAO的register方法   
  1. 接口注入
  2. 不同数据类型的依赖注入
  3. 基本数据类型 字符串(value)
xml文件
  • name:数据类中的成员变量的参数名
  • value:赋值
   <!--不同数据类型的依赖注入  -->
   <bean id="student" class="Spring.bean.Student">
       <property name="sid" value="111"/>
       <property name="sname" value="xiaoli"/>
       <property name="sex" value="女"/>
       <property name="email" value="111@qq.com"/>
       
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
                <value>333</value>
            </list>
        </property>
   </bean>
bean.java
  • 只提供参数的 set 方法
public class Student {
    private int sid;
    private String sname;
    private String sex;
    private String email;
    private List<String> list;
    
    
    
    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void setEmail(String email) {
        this.email = email;
    }


    public void printInfo() {
        System.out.println(sid+" "+sname+" "+sex+" "+email);
        for(String s:list) {
            System.out.println(s);
        }
    }

}
Test
        //不同数据类型的依赖注入(属性注入)
        Student stu = (Student) app.getBean("student");
        stu.printInfo();//111 xiaoli 女 111@qq.com
  1. 空值的依赖注入
   <bean id="student" class="Spring.bean.Student">
       <property name="sid" value="111"/>
       <property name="sname" value="xiaoli"/>
       <property name="sex" value="女"/>
     //空值
      <property name="email" value=""/> 
        
        <!-- 
        <property name="email"/>
         <null/> 
        -->
        
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
                <value>333</value>
            </list>
        </property>
   </bean>

  1. 引用数据类型的依赖注入(ref)
xml文件
    <!-- 构造注入 -->
    <bean id="example" class="Spring.bean.ExampleBean">

        <constructor-arg>
            <ref bean="first"/>
        </constructor-arg>
        <constructor-arg>
            <ref bean="second"/>
        </constructor-arg>
        
    </bean>
    
   <!-- 属性注入 -->
   <bean id="newexample" class="Spring.bean.NewExampleBean">
   <!-- 
       property标签:
       name:与类中类中成员变量的名字相同
       ref:要注入的bean的id
    -->
        <property name="firstBean" ref="first"/>
        <property name="secondBean" ref="second"></property>
   </bean>
   
   <bean id="userDAO" class="Spring.dao.UserDAO"></bean>
   <bean id="userService" class="Spring.service.UserService">
   <property name="dao" ref="userDAO"></property>
       
   </bean>
  1. 集合类型的依赖注入

基于注解的配置

注解形式开发
xml文件
 <!--  组件扫描管理某个包中所有类的对象  -->
    <context:component-scan base-package="com.service"></context:component-scan>
    <context:component-scan base-package="com.dao"></context:component-scan>
在service层的注解中起别名是在Test中 app.getBean() 方法中调用
Test
        UserService service = (UserService) app.getBean("userService");
        service.login();//UserService的login的方法  UserDAO的login的方法

Spring AOP:解决事务处理

举个栗子:记录程序运行的时间
实现思路:把横切关注点的功能代码单独用一个类去实现,在程序编译或者运行期间,动态的加如该部分代码
  1. 通知:用于编写横切关注点的代码的类
  • 前置通知: 通知的代码在业务代码执行之 就执行完毕
  • 返回后通知: 通知的代码在业务代码执行之 就执行完毕
  • 环绕通知:通知的代码在业务代码执行之 就执行,在业务代码执行之 也会执行
bean.java
//环绕通知
public class SelectAdvice implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation method) throws Throwable {
        
        System.out.println("程序运行开始");
        Date begin = new Date();
        
        //继续执行业务代码
        Object obj =  method.proceed();
        
        System.out.println("程序运行结束");    
        Date end = new Date();
        
        System.out.println("程序运行时间为:"+(end.getTime()-begin.getTime())+"毫秒");
        return obj;
    }

}
  • 抛出通知:业务代码抛出异常时执行通知类代码
  1. 切入点:定义横切关注点的代码 何时 被执行
  2. 顾问:切入点与通知的配置器
  3. 代理:实现
xml文件:4步走
    <bean id="select1" class="spring.aop.bean.UserSelectImp1" />
    
    <bean id="select2" class="spring.aop.bean.UserSelectImp2" />
   <!-- 管理通知类对象 -->
    <bean id="selectAdvice"  class="spring.aop.bean.SelectAdvice" />
   <!-- 配置切入点 -->
    <bean id="selectPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"  >
        <property name="pattern"  value=".*select" />
    </bean>
   <!-- 配置顾问 -->
   <bean id="selectAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"  >
        <property name="advice"  ref="selectAdvice" />
        <property name="pointcut"  ref="selectPointcut" />
   </bean>
   <!-- 代理 -->
   <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  />

Test
    public static void main(String[] args) {
        //加载Spring容器 入参是Spring核心配置文件相当于src的路径
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        UserSelect s1 = (UserSelect) app.getBean("select1");
        s1.select();
        
        UserSelect s2 = (UserSelect) app.getBean("select2");
        s2.select(); 

    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容