<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring 的IOC和AOP以及動(dòng)態(tài)代理

          共 15605字,需瀏覽 32分鐘

           ·

          2021-04-25 10:08

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          76套java從入門到精通實(shí)戰(zhàn)課程分享

          依賴

          class a中使用class b的屬性或者方法, 叫做classa依賴classb


          Spring

          1. IOC(控制反轉(zhuǎn))

          IoC (Inversion of Control) : 控制反轉(zhuǎn), 是一個(gè)理論,概念,思想。

          描述的:把對(duì)象的創(chuàng)建,賦值,管理工作都交給代碼之外的容器實(shí)現(xiàn)。


          控制: 創(chuàng)建對(duì)象,對(duì)象的屬性賦值,對(duì)象之間的關(guān)系管理。

          反轉(zhuǎn): 把容器代替開(kāi)發(fā)人員管理對(duì)象。創(chuàng)建對(duì)象,給屬性賦值。


          正轉(zhuǎn):由開(kāi)發(fā)人員在代碼中,使用new 構(gòu)造方法創(chuàng)建對(duì)象, 開(kāi)發(fā)人員主動(dòng)管理對(duì)象。

          public static void main(String args[]){
                  Student student = new Student(); // 在代碼中, 創(chuàng)建對(duì)象。--正轉(zhuǎn)。

            }

          容器:是一個(gè)服務(wù)器軟件, 一個(gè)框架(spring)


          為什么要使用 ioc :


          目的就是減少對(duì)代碼的改動(dòng), 也能實(shí)現(xiàn)不同的功能。 實(shí)現(xiàn)解耦合


          java中創(chuàng)建對(duì)象有哪些方式:

          1. 構(gòu)造方法 , new Student()
            2. 反射
            3. 序列化
            4. 克隆
            5. ioc :容器創(chuàng)建對(duì)象
            6. 動(dòng)態(tài)代理

          ioc的體現(xiàn):

          servlet  1: 創(chuàng)建類繼承HttpServelt 
                    2:  在web.xml 注冊(cè)servlet , 使用
                    <servlet-name> myservlet </servlet-name>
                                               <servelt-class>com.bjpwernode.controller.MyServlet1</servlet-class>

                      3. 沒(méi)有創(chuàng)建 Servlet對(duì)象, 沒(méi)有 MyServlet myservlet = new MyServlet()

              4. Servlet 是Tomcat服務(wù)器它能你創(chuàng)建的。 Tomcat也稱為容器
                 Tomcat作為容器:里面存放的有Servlet對(duì)象, Listener , Filter對(duì)象

          junit : 單元測(cè)試, 一個(gè)工具類庫(kù),做測(cè)試方法使用的。

          使用單元測(cè)試
             1.需要加入junit依賴。
             <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
              </dependency>

            2.創(chuàng)建測(cè)試作用的類:叫做測(cè)試類
              src/test/java目錄中創(chuàng)建類

            3.創(chuàng)建測(cè)試方法

              1)public 方法
            2)沒(méi)有返回值 void 
            3)方法名稱自定義,建議名稱是test + 你要測(cè)試方法名稱
            4)方法沒(méi)有參數(shù)
            5)方法的上面加入 @Test ,這樣的方法是可以單獨(dú)執(zhí)行的。 不用使用main方法

          IOC如何創(chuàng)建對(duì)象


          1、聲明一個(gè)bean,就是告訴spring要?jiǎng)?chuàng)建某個(gè)類的對(duì)象

          id:對(duì)象的自定義名稱,spring就是通過(guò)這個(gè)ID找到對(duì)象

          class:類的全路徑名稱

          Spring b把創(chuàng)建的對(duì)象放在map集合,

          SpringMap.put(id , 對(duì)象)

          xml文件 這就創(chuàng)建對(duì)象了
          <bean id = "要?jiǎng)?chuàng)建對(duì)象的類名 別名 也可以是一樣的 如:SomeServiceImpl的別名someService" class = "SomeServiceImpl的全路徑名稱" />

          一個(gè)測(cè)試類 
          @Test
          public voidtest(){
           // 使用spring容器創(chuàng)建對(duì)象
           1、指定spring配置文件的名稱
           
           String config = "bean.xml";
           
              2、創(chuàng)建spring容器對(duì)象 ApplicationContext
              
              ApplicationContext ac = new ClassPathXmlApplicationContext(config);
              
              3、從容器中取對(duì)象 getbean(配置文件中bean的id)
              
              SomeService s = (SomeService)ac.getbean("someService");
              
           4、使用spring創(chuàng)建對(duì)象
           s.dosome();  // dosome 是SomeService類中的方法
           
          }

          如同 SomeServiceImpl s = new SomeServiceImpl();

          s.dosome();


          IoC的技術(shù)實(shí)現(xiàn)


          DI 是ioc的技術(shù)實(shí)現(xiàn),

          DI(Dependency Injection) :依賴注入, 只需要在程序中提供要使用的對(duì)象名稱就可以, 至于對(duì)象如何在容器中創(chuàng)建,

          賦值,查找都由容器內(nèi)部實(shí)現(xiàn)。

          spring是使用的di實(shí)現(xiàn)了ioc的功能, spring底層創(chuàng)建對(duì)象,使用的是反射機(jī)制。

          spring是一個(gè)容器,管理對(duì)象,給屬性賦值, 底層是反射創(chuàng)建對(duì)象。


          set方法注入

          類:
          public class Student(){
           private String name;
           private int age;
           private School school; //引用數(shù)據(jù)類型
           無(wú)參構(gòu)造函數(shù)
           有參的構(gòu)造函數(shù)
           
           
           private void setName(String name){
            this.name = name;
           }
           private void setAge(int age){
            this.age= age;
           }
           private void setschool(School school){
            this.school= school;
           }
          }
          public class School (){
           private String name;
              無(wú)參構(gòu)造函數(shù)
           有參的構(gòu)造函數(shù)
            
           private void setName(String name){
            this.name = name;
           }
           
           
          }

          Spring 調(diào)用類中的set方法,給參數(shù)注入值

          語(yǔ)法:


          簡(jiǎn)單類型的set注入

          > 1、語(yǔ)法
          > > <bean id = "要?jiǎng)?chuàng)建對(duì)象的類名 如:someService" class = "SomeService的全路徑名稱" >
            <property name = "參數(shù)名" value="值"/>
          </bean>



          xml文件
          <bean id = "student" class = "Student的全路徑名稱" >
            <property name = "name" value="老師"/>
            <property name = "age" value="20"/>
          </bean>

          引用數(shù)據(jù)類型的set注入


          2、語(yǔ)法
          <bean id = "要?jiǎng)?chuàng)建對(duì)象的類名 如:someService" class = "SomeService的全路徑名稱" >
            <property name = "參數(shù)名" ref=" 要引用的對(duì)象的bean的id"/>
          </bean>

          <bean id = "student" class = "Student的全路徑名稱" >
            <property name = "name" value="老師"/>
            <property name = "age" value="20"/>
            <property name = "school" ref="school"/>
          </bean>
          <bean id = "school" class = "School的全路徑名稱" >
            <property name = "name" value="清華"/> 
          </bean>


          構(gòu)造方法的注入

          spring調(diào)用有參構(gòu)造方法。在創(chuàng)建對(duì)象的時(shí)候注入值

          語(yǔ)法
          <bean id = "要?jiǎng)?chuàng)建對(duì)象的類名 如:someService" class = "SomeService的全路徑名稱" >
            <donstructor-arg name = "參數(shù)名" value = "值"/>  name :構(gòu)造方法的形參名  
            或者
            <donstructor-arg index= "0" value = "值"/>  index 構(gòu)造方法的形參名的位置 0  1  2 
             或者
             value 構(gòu)造方法的形參是簡(jiǎn)單類型的
             ref:構(gòu)造方法形參是引用類型
          </bean>


          <bean id = "student" class = "Student的全路徑名稱" >
            <donstructor-arg name = "name" value = "張三"/> 
            <donstructor-arg name = "age" value = "20"/>  name :構(gòu)造方法的形參名  
            或者
            <donstructor-arg index= "0" value = "張三"/>  index 構(gòu)造方法的形參名的位置 0  1  2 
            <donstructor-arg index= "1" value = "20"/>
               <donstructor-arg index= "3" ref= "school"/>
             ref:構(gòu)造方法形參是引用類型s
             
          </bean>
          <bean id = "school" class = "School的全路徑名稱" >
            <property name = "name" value="清華"/> 
          </bean>

          引用數(shù)據(jù)類型的自動(dòng)注入

          byName

          1、byName(按名稱注入):Java類中引用數(shù)據(jù)類型的屬性名和spring容器中(配置文件)引用類性的bean id 名一樣 
          <bean id = "myStudent" class = "Student的全路徑名稱" autowire = "byName">
            基本數(shù)據(jù)類型的賦值
            </bean>

          <bean id = "myStudent" class = "Student的全路徑名稱" autowire = "byName">
            <donstructor-arg name = "name" value = "張三"/> 
            <donstructor-arg name = "age" value = "20"/>  name :構(gòu)造方法的形參名  
             
               // <donstructor-arg index= "3" ref= "school"/>
             ref:構(gòu)造方法形參是引用類型
          </bean>
          <bean id = "school" class = "School的全路徑名稱" >
            <property name = "name" value="清華"/> 
          </bean>

          byType

          byType:按照類型注入 
              Java類中引用類型的數(shù)據(jù)類型和spring容器中(配置文件)bean 的class 屬性是同源關(guān)系的 如在一個(gè)包下
              同源 就是一類的意思
              1、Java類中引用類型 的數(shù)據(jù)類型和bean的class的值一樣
              2、Java類引用類型的數(shù)據(jù)類型和bean的class的值是父字關(guān)系
              3、Java類引用類型的數(shù)據(jù)類型和bean的class的值是接口和實(shí)現(xiàn)類的關(guān)系
          語(yǔ)法

          <bean id = "myStudent" class = "Student的全路徑名稱" autowire = "byType">
            基本數(shù)據(jù)類型的賦值
            </bean>

          <bean id = "myStudent" class = "Student的全路徑名稱" autowire = "byType">
            <donstructor-arg name = "name" value = "張三"/> 
            <donstructor-arg name = "age" value = "20"/>  name :構(gòu)造方法的形參名  
             
               // <donstructor-arg index= "3" ref= "school"/>
             ref:構(gòu)造方法形參是引用類型
          </bean>
          <bean id = "school" class = "School的全路徑名稱" >
            <property name = "name" value="清華"/> 
          </bean>

          管理對(duì)各配置文件

          多個(gè)配置文件: 一個(gè)模塊一個(gè)文件

          如 學(xué)生一個(gè)

          班級(jí)一個(gè)

          學(xué)習(xí)一個(gè)

          語(yǔ)法
          再創(chuàng)建一個(gè)主配置文件
          <beans>
           <import resource = ClassPath:其他配置文件的路徑
          </beans>

          <beans>
           <import resource = ClassPath:student.xml的路徑
           <import resource = ClassPath:student.xml的路徑
          </beans>

          使用注解注入

          通過(guò)注解完成對(duì)象的創(chuàng)建,代替xml

          1、加入spring-context依賴

          2、在類中創(chuàng)建注解

          3、創(chuàng)建spring的配置文件

          掃描器:指定注解在項(xiàng)目中的位置

          4、使用注解創(chuàng)建對(duì)象,創(chuàng)建容器ApplicationContext


          @Component(對(duì)象的名稱也就是bean的id)

          此注解創(chuàng)建對(duì)象 等同 bean的功能 等同于

          位置:類的上面

          @Component() 默認(rèn)名稱 類名的首字母小寫 student


          配置文件


          配置掃描器:component - scan

          base-package:注解在項(xiàng)目的包名

          工作方法 :spring掃碼指定的包 找到注解 創(chuàng)建對(duì)象 賦值

          三種方法
          1、 <context:component-scan_base-package="包名1">
           <context:component-scan_base-package="包名2">
          2、<context:component-scan_base-package="包名1;包名2">
          3、指定父包 
          <context:component-scan_base-package="父包名">

          @Component("student")
          public class Student(){
           private String name;
           private int age;
           private School school; //引用數(shù)據(jù)類型
           無(wú)參構(gòu)造函數(shù)
           有參的構(gòu)造函數(shù)
           
           
           private void setName(String name){
            this.name = name;
           }
           private void setAge(int age){
            this.age= age;
           }
           private void setschool(School school){
            this.school= school;
           }
          }

          其他創(chuàng)建對(duì)象的注解

          這三個(gè)給項(xiàng)目分層


          @Repository() 用在持久層,dao的實(shí)現(xiàn)類上面 表示創(chuàng)建對(duì)象dao能訪問(wèn)數(shù)據(jù)庫(kù)

          @Service()業(yè)務(wù)層在service的實(shí)現(xiàn)類上,創(chuàng)建service對(duì)象,做業(yè)務(wù)處理,有事務(wù)等功能

          @Controller() 控制層:創(chuàng)建控制器對(duì)象,接收用戶處理的參數(shù),顯示請(qǐng)求的結(jié)果

          注解注入賦值

          @Value(“張飛”) :簡(jiǎn)單數(shù)據(jù)類型賦值

          用在String 類型上,基本數(shù)據(jù)類型不OK 可以使用包裝類

          無(wú)需set方法

          位置 參數(shù)上

           @Value("李雙")
           private String name;
           @Value("20")
           private int age;
            //引用數(shù)據(jù)類型


          引用數(shù)據(jù)類型注解注入@Autowired

          :自動(dòng)注入原理 支持byName 、byType; 默認(rèn)byType

          位置:在屬性的上面

          屬性:required = true 賦值失敗程序報(bào)錯(cuò)

          required = false 賦值失敗正常執(zhí)行、引用數(shù)據(jù)為null

             @Autowired
           private int age;

          使用byName

          在屬性上加@Autowired

          @Qualifier(value = “bean的id”)表示指定名稱的bean完成賦值

          @Autowired
          @Qualifier("school")
          private School school;

          引用數(shù)據(jù)類型注解賦值@Resource

          默認(rèn)byName 失敗用byType

          位置參數(shù)上面

          @Resource
          private School school

          --------------------AOP切面--------------------

          動(dòng)態(tài)代理

          1、實(shí)現(xiàn)方法:jdk動(dòng)態(tài)代理,使用jdk中的Proxy,Method,InvocaitonHanderl創(chuàng)建代理對(duì)象。

          jdk動(dòng)態(tài)代理要求目標(biāo)類必須實(shí)現(xiàn)接口

          2.動(dòng)態(tài)代理的作用:

          1)在目標(biāo)類源代碼不改變的情況下,增加功能。

          2)減少代碼的重復(fù)

          3)解耦合。


          步驟:

          1、 定義一個(gè)接口
          2、定義一個(gè)類ServiceTools 類中有共有的方法 (時(shí)間、事務(wù))doLog();doTrans();
          2、定義一個(gè)接口的實(shí)現(xiàn)類,繼承接口 重新方法 doSome();

          3、寫代理類:

          繼承IncationHandler實(shí)現(xiàn)代理

          public Class MyIncationHandler implement IncationHandler(){
           private Object target;// 實(shí)現(xiàn)類
           public MyIncationHandler(Object target){
            this target = target;
           }
           public Object invoke(Object proxy,Method method, Object[] args)throws Throwable{
            // 通過(guò)代理對(duì)象執(zhí)行方法 會(huì)調(diào)用這個(gè)invoke()
            Object res = null;
            ServiceTools.doLog();
            // 執(zhí)行目標(biāo)類的方法,通過(guò)Method類實(shí)現(xiàn)
            res = method.invoke(target,args);//執(zhí)行實(shí)現(xiàn)類的方法
            ServiceTools.doTrans();
            // 目標(biāo)方法的執(zhí)行結(jié)果
            return res;
            
           }
          }

          使用jdk實(shí)現(xiàn)代理

          public class MyApp(){
           public static void main(String[] args){
            SomeService target = new 實(shí)現(xiàn)類;
            // 創(chuàng)建InvocationHandler
            InvocationHandler handler = new MyIncationHandler(target);
            // 使用proxy創(chuàng)建代理
            SomeService proxy = (SomeService)Proxy.newProxyInsstance{
             target.getClass().getClassLoader(),
             target.getClass().getInterFaces(),Handler);
             // 調(diào)用handler中的invoke();
             proxy.dosome();
            }
           }
          }

          aspectj實(shí)現(xiàn)AOP

          步驟

          1、新建maven項(xiàng)目

          2、加入依賴

          aspectj依賴

          juint單元測(cè)試

          3、創(chuàng)建目標(biāo)類:接口和實(shí)現(xiàn)類

          4、創(chuàng)建切面類:普通類

          (1)在類上加入@Aspect

          (2) 在類中的定義方法,方法就是切面執(zhí)行的代碼(事務(wù)、日志、時(shí)間等)

          在方法上加入aspectj的通知注解。如@before

          有需要?jiǎng)t指定切入表達(dá)式

          5、創(chuàng)建spring配置文件,聲明對(duì)象,把對(duì)象交給IOC管理

          (1)聲明目標(biāo)對(duì)象

          (2)聲明切面類對(duì)象

          (3)聲明aspectj框架中自動(dòng)代理生成器標(biāo)簽

          6創(chuàng)建測(cè)試類


          接口`

          public interface SomeService{
           void doSome(String name,Integer age);
          }

          實(shí)現(xiàn)類

          public class SomeServiceImpl implements SomeService {
           @Override
           public void doSome(String name,Integer age){
           Sysotem.out.println("執(zhí)行----------")
           }
          }

          切面類

          @Aspect
          public class MyAspect{
           方法要求
            1、public
            2、void
            3、方法名自定義
            4、方法可以有參數(shù)也可以無(wú)參數(shù)
            5、@Before前置注解 
             1、屬性 Value 切入表達(dá)式,表示切面的執(zhí)行位置
             2、位置 :在方法的上面
             
           @Before(value = "execution(public void 包下的實(shí)現(xiàn)類.doSome(String,Integer)")
           public void myBefore(){
           //切面的代碼
            Sysotem.out.println("時(shí)間----------")
           }
          }

          配置文件

          // 聲明目標(biāo)類(實(shí)現(xiàn)類)對(duì)象
          <bean id = "someService" class = "路徑名" />
          // 聲明切面類對(duì)象
          <bean id = "myAspect" class = "全路徑名" />

          //聲明aspectj框架中自動(dòng)代理生成器標(biāo)簽
          <aop:aspectj-autoproxy>

          后置通知@AfterReturn()

          要求
          1、public
          2、void
          3、方法有參數(shù) Object 方法名自定義
          4、屬性 1、value:切入點(diǎn)表達(dá)式
            2、returning 自定義的變量,便是目標(biāo)方法有返回值的
            自定義的變量名必須和通知方法的形參一樣
          位置: 方法上面


          切面類 中的方法
          @@AfterReturn(value = "execution(public void 包下的實(shí)現(xiàn)類.doSome(String,Integer)",returning = "res")
           public void myAfterReturn(Object res){  res 和,returning = "res一樣
           //切面的代碼
            Sysotem.out.println("
          時(shí)間----------")

          環(huán)繞通知@Around

          屬性:value:切入表達(dá)式

          位置:方法上方


          特點(diǎn)

          功能最強(qiáng)的通知

          在目標(biāo)方法前后都能加入切面類的代碼

          控制目標(biāo)方法是否調(diào)用執(zhí)行

          修改原目標(biāo)方法的執(zhí)行結(jié)果,影響最后的調(diào)用結(jié)果

          @Around(value = "execution(public void 包下的實(shí)現(xiàn)類.doSome(String,Integer)")
          public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
           // 實(shí)現(xiàn)環(huán)體通知
           Object result = null;
           Sysotem.out.println("方法前")
           // 目標(biāo)方法調(diào)用
           result = pjp.proceed(); 
           Sysotem.out.println("方法后")
           // 返回目標(biāo)方法的執(zhí)行結(jié)果
           return result;

          }

          ————————————————

          版權(quán)聲明:本文為CSDN博主「ジ你是我永遠(yuǎn)のbugグ」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

          原文鏈接:

          https://blog.csdn.net/qq_47848696/article/details/115838386






          粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

          ??????

          ??長(zhǎng)按上方微信二維碼 2 秒


          感謝點(diǎn)贊支持下哈 

          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花视频官方网站入口在线观看 | 国产永久性人人视频 | 大鸡巴日骚逼视频 | 久久超碰大香蕉 | 青娱乐亚洲日韩 |