<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] ## 1. AOP > * AOP :面向切面編程思想 > 1. 橫向重復代碼,縱向抽取。 > * 動態代理: > 1. 可以體現AOP思想 > 2. 對對象中的方法進行增強 > * Spring aop開發 > 1. Spring封裝了動態代理的代碼,我們就不需要手寫動態代理代碼 > 2. 還封裝了cglib代理 > 3. 1和2使Spring對任何類進行增強 ![](https://box.kancloud.cn/ce31c3d2345d2f016c2f401bb38a4f96_986x401.png) 有接口優先使用動態代理,否則使用cglib代理 ### 1.1 動態代理 測試 代理類接口 ~~~ package com.aixin.daili; /** * Created by dailin on 2017/12/12. */ public interface UserService { void save(); void update(); void delete(); void select(); } ~~~ 代理實現類 ~~~ package com.aixin.daili; /** * Created by dailin on 2017/12/12. */ public class UserServiceImpl implements UserService { public void save() { System.out.println("保存用戶"); } public void update() { System.out.println("更新用戶"); } public void delete() { System.out.println("刪除用戶"); } public void select() { System.out.println("查找用戶"); } } ~~~ 代理工廠 ~~~ package com.aixin.c_proxy; import com.aixin.daili.UserService; import com.aixin.daili.UserServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by dailin on 2017/12/12. */ public class UserServiceProxyFactory implements InvocationHandler{ private UserService us; //被代理對象 public void setUs(UserService us) { this.us = us; } public UserServiceProxyFactory(UserService us) { this.us = us; } public UserService getUserServiceProxy(){ //生成動態代理對象 UserService usPrxoy = (UserService)Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), this); return usPrxoy; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("打開事務!"); Object obj = method.invoke(us, args); System.out.println("提交事務"); return obj; } } ~~~ 測試 ~~~ package springTest.ProxyTest; import com.aixin.c_proxy.UserServiceProxyFactory; import com.aixin.daili.UserService; import com.aixin.daili.UserServiceImpl; import org.junit.Test; /** * Created by dailin on 2017/12/12. */ public class test { @Test public void testDongtai() { UserService us = new UserServiceImpl(); //被代理對象 UserServiceProxyFactory userServiceProxyFactory = new UserServiceProxyFactory(us); UserService user = userServiceProxyFactory.getUserServiceProxy(); //獲取代理對象 user.save(); //調用方法 } } ~~~ ### 1.2 cglib代理 ~~~ package cn.itcast.c_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import cn.itcast.service.UserService; import cn.itcast.service.UserServiceImpl; //觀光代碼=>cglib代理 public class UserServiceProxyFactory2 implements MethodInterceptor { public UserService getUserServiceProxy(){ Enhancer en = new Enhancer();//幫我們生成代理對象 en.setSuperclass(UserServiceImpl.class);//設置對誰進行代理 en.setCallback(this);//代理要做什么 UserService us = (UserService) en.create();//創建代理對象 return us; } @Override public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable { //打開事務 System.out.println("打開事務!"); //調用原有方法 Object returnValue = methodProxy.invokeSuper(prxoyobj, arg); //提交事務 System.out.println("提交事務!"); return returnValue; } } ~~~ ### 1.3 名詞解釋 ![](https://box.kancloud.cn/7f3678e465945d45b677399bc775a5f2_870x493.png) ### 1.4 spring AOP #### 1.4.1 xml AOP 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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.aixin.bean"></context:component-scan> <!-- 1. 配置目標對象 --> <bean name="userService" class="com.aixin.daili.UserServiceImpl"></bean> <!-- 2. 配置通知對象 --> <bean name="myAdvice" class="com.aixin.c_proxy.MyAdvice"></bean> <!-- 3. 配置將通知組織入對象 --> <aop:config> <!-- 1. 配置切點 public void com.aixin.daili.UserServiceImpl.save())" public 可省略 * 代替返回值 空參 * com.aixin.daili.UserServiceImpl.*() * com.aixin.daili.UserServiceImpl.*(..) 不要求參數 * com.aixin.daili.*ServiceImpl.*(..) 不要求參數,所有ServiceImpl .. 表示子包和子包的所有包 --> <aop:pointcut id="pc" expression="execution(* com.aixin.daili.*ServiceImpl.*(..))"></aop:pointcut> <aop:aspect ref="myAdvice"> <aop:before method="before" pointcut-ref="pc"/> <aop:after method="afterRunning" pointcut-ref="pc"/> <aop:around method="around" pointcut-ref="pc"/> <aop:after-throwing method="afterException" pointcut-ref="pc"/> <aop:after method="after" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans> ~~~ 通知類 ~~~ package com.aixin.c_proxy; import org.aspectj.lang.ProceedingJoinPoint; /** * Created by dailin on 2017/12/12. * 通知類 */ public class MyAdvice { //前置通知 // |-目標方法執行前調用 //后置通知 (如果出現異常不會調用) // |-目標方法執行后調用 //環繞通知 // |-目標方法執行前后都調用 //異常攔截通知 // |-如果出現異常調用 //后置通知(無論是否出現 異常都會調用 // |-目標方法運行后 //前置通知 public void before(){ System.out.println("前置通知。。。"); } //后置通知 public void afterRunning(){ System.out.println("后置通知(如果出現異常不會調用)。。。"); } public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("環繞通知前。。。"); Object proceed = pjp.proceed(); System.out.println("環繞通知后。。。"); return proceed; } public void afterException(){ System.out.println("出現異常。。。"); } //后置通知 public void after(){ System.out.println("后置通知。。。"); } } ~~~ #### 1.4.2 注解式AOP ~~~ //通知類 @Aspect //表示該類是一個通知類 public class MyAdvice { // 這樣就不用每個通知都要寫切入點表達式了 @Pointcut("execution(* cn.itcast.service.*ServiceImpl.*(..))") public void pc(){} //前置通知 //指定該方法是前置通知,并制定切入點 @Before("MyAdvice.pc()") public void before(){ System.out.println("這是前置通知!!"); } //后置通知 @AfterReturning("execution(* cn.itcast.service.*ServiceImpl.*(..))") public void afterReturning(){ System.out.println("這是后置通知(如果出現異常不會調用)!!"); } //環繞通知 @Around("execution(* cn.itcast.service.*ServiceImpl.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("這是環繞通知之前的部分!!"); Object proceed = pjp.proceed();//調用目標方法 System.out.println("這是環繞通知之后的部分!!"); return proceed; } //異常通知 @AfterThrowing("execution(* cn.itcast.service.*ServiceImpl.*(..))") public void afterException(){ System.out.println("出事啦!出現異常了!!"); } //后置通知 @After("execution(* cn.itcast.service.*ServiceImpl.*(..))") public void after(){ System.out.println("這是后置通知(出現異常也會調用)!!"); } } ~~~ ## 2. 三種對象創建方式 ### 2.1 三種方式 ~~~ <?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"> <!-- 創建方式1:空參構造 --> <bean name="user" class="com.aixin.bean.User"></bean> <!-- 創建方式2:靜態工廠創建,由靜態工廠類創建對象并放入容器 --> <bean name="user2" class="com.aixin.bean.UserFactory" factory-method="createUser"></bean> <!-- 創建方式3:實例工廠對象創建 調用userfactory對象創建對象 --> <bean name="user3" factory-bean="userfactory" factory-method="createUser2"></bean> <bean name="userfactory" class="com.aixin.bean.UserFactory"></bean> </beans> ~~~ ### 2.2 scope 控制對象(bean)的數量 ![](https://box.kancloud.cn/810c968474c2122c650d476bd8fb9457_520x193.png) ## 3. 屬性注入 ~~~ public class User { public User() { System.out.println("User對象空參構造方法!!!!"); } private String name; private Integer age; private Car car; public User(String name, Car car) { System.out.println("User(String name, Car car)!!"); this.name = name; this.car = car; } public User(Car car,String name) { System.out.println("User(Car car,String name)!!"); this.name = name; this.car = car; } public User(Integer name, Car car) { System.out.println("User(Integer name, Car car)!!"); this.name = name+""; this.car = car; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public void init(){ System.out.println("我是初始化方法!"); } public void destory(){ System.out.println("我是銷毀方法!"); } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", car=" + car + "]"; } } ~~~ ### 3.1 set方法注入屬性 ~~~ <!-- set方式注入: --> <bean name="user" class="cn.itcast.bean.User" > <!--值類型注入: 為User對象中名為name的屬性注入tom作為值 --> <property name="name" value="tom" ></property> <property name="age" value="18" ></property> <!-- 引用類型注入: 為car屬性注入下方配置的car對象 --> <property name="car" ref="car" ></property> </bean> <!-- 將car對象配置到容器中 --> <bean name="car" class="cn.itcast.bean.Car" > <property name="name" value="蘭博基尼" ></property> <property name="color" value="黃色" ></property> </bean> ~~~ ### 3.2 構造函數 > name屬性: 構造函數的參數名 > index屬性: 構造函數的參數索引 > type屬性: 構造函數的參數類型 ~~~ <!-- 將car對象配置到容器中 --> <bean name="car" class="cn.itcast.bean.Car" > <property name="name" value="蘭博基尼" ></property> <property name="color" value="黃色" ></property> </bean> <!-- ============================================================ --> <!-- 構造函數注入 --> <bean name="user2" class="cn.itcast.bean.User" > <!-- name屬性: 構造函數的參數名 --> <!-- index屬性: 構造函數的參數索引 --> <!-- type屬性: 構造函數的參數類型--> <constructor-arg name="name" index="0" type="java.lang.Integer" value="999" ></constructor-arg> <constructor-arg name="car" ref="car" index="1" ></constructor-arg> </bean> ~~~ ### 3.3 p名稱空間注入 p名稱空間注入, 走set方法 1.導入P名稱空間 xmlns:p="http://www.springframework.org/schema/p" 2.使用p:屬性完成注入 |-值類型: p:屬性名="值" |-對象類型: p:屬性名-ref="bean名稱" ~~~ <bean name="user3" class="cn.itcast.bean.User" p:name="jack" p:age="20" p:car-ref="car" > </bean> ~~~ ### 3.4 spel注入 spel注入: spring Expression Language sping表達式語言 <bean name="user4" class="cn.itcast.bean.User" > <property name="name" value="#{user.name}" ></property> <property name="age" value="#{user3.age}" ></property> <property name="car" ref="car" ></property> </bean> ## 4. 注解注入 context 掃描包 ~~~ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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"> <context:component-scan base-package="com.aixin.bean"></context:component-scan> </beans> ~~~ 1. 創建對象 ~~~ //@Component("user") // @Service("user") // service層 // @Controller("user") // web層 @Repository("user")// dao層 ~~~ 2. 屬性自動注入 ~~~ //@Autowired //自動裝配 //問題:如果匹配多個類型一致的對象.將無法選擇具體注入哪一個對象. ~~~ * 自動選擇注入 3. 初始化與銷毀(銷毀得是單例) ~~~ @PostConstruct //在對象被創建后調用.init-method @PreDestroy //在銷毀之前調用.destory-method ~~~ ~~~ @Autowired @Qualifier("car2") //@Qualifier("car2")//使用@Qualifier注解告訴spring容器自動裝配哪個名稱的對象 ~~~ ~~~ package cn.itcast.bean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.xml.ws.RespectBinding; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; //<bean name="user" class="cn.itcast.bean.User" /> //@Component("user") // @Service("user") // service層 // @Controller("user") // web層 @Repository("user")// dao層 //指定對象的作用范圍 @Scope(scopeName="singleton") public class User { private String name; @Value("18") private Integer age; //@Autowired //自動裝配 //問題:如果匹配多個類型一致的對象.將無法選擇具體注入哪一個對象. //@Qualifier("car2")//使用@Qualifier注解告訴spring容器自動裝配哪個名稱的對象 @Resource(name="car")//手動注入,指定注入哪個名稱的對象 private Car car; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public String getName() { return name; } @Value("tom") public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @PostConstruct //在對象被創建后調用.init-method public void init(){ System.out.println("我是初始化方法!"); } @PreDestroy //在銷毀之前調用.destory-method public void destory(){ System.out.println("我是銷毀方法!"); } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", car=" + car + "]"; } } ~~~ #### 注解 ~~~ package com.bean; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * Created by dailin on 2017/12/13. */ @Component //根據類名生成以類名首字母小寫的對象 public class Car { private String name; private String color; public String getName() { return name; } public void setName(String name) { this.name = name; } } ~~~ 把car注入到人 ~~~ package com.bean; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * Created by dailin on 2017/12/13. */ @Component("user") //給對象起名,不起按照類首字母小寫規則生成對象 public class User { private Integer id; private String name; @Resource private Car car; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Car getCar() { return car; } @Override public String toString() { return getName()+getCar(); } } ~~~ 測試 ~~~ public class test { @org.junit.Test public void test(){ ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application2.xml"); User us = (User) classPathXmlApplicationContext.getBean("user"); System.out.println(us); } } ~~~ 得到 ~~~ nullcom.bean.Car@19dc67c2 ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看