Java mac idea spring的使用02

1.使用注解配置spring

1.1 引入新的命名空間(約束)

如果是使用eclipse的同學(xué),那么肯定是很熟悉這個(gè)了。使用idea的話,就不需要自己引入了,idea已經(jīng)將約束添加好了

1.2 在spring的配置文件中開啟注解

<!--指定掃面 bean 包下的所有類 的注解-->
    <context:component-scan base-package="bean"/>

1.3 在類中使用注解

// 相當(dāng)于在xml配置文件中寫<bean name="user" class="bean.user" />
@Component("user") // 早期使用,當(dāng)初只有component,后續(xù)細(xì)化出了下面三個(gè),用于不同的層,方便閱讀
    @Service("user")    // service層
    @Controller("user") // web層
    @Repository("user") // dao層

1.4 測試

@Test
    public void testFunc01() {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        User user = (User) applicationContext.getBean("user");

        System.out.println(user);
    }

2. 使用注解

2.1 使用Scpoe

@Repository("user") // dao層
@Scope("prototype")
public class User {
    private String name;
    private Integer age;
    private Dog dog;

2.2 基本數(shù)據(jù)類型賦值

  1. 在屬性上賦值
    通過反射的field賦值,破壞封裝性,但是可讀性好
public class User {
    @Value("tom")
    private String name;

    @Value("18")
    private Integer age;
  1. 在set方法上賦值
    在set方法賦值,推薦使用,但是可讀性不太好
@Value("tom")
    public void setName(String name) {
        this.name = name;
    }

    @Value("18")
    public Integer getAge() {
        return age;
    }

2.3 引用類型賦值

先給dog類賦值

@Component("dog")
public class Dog {

    @Value("柯基")
    private String name;
    @Value("3")
    private Integer age;
  1. 手動(dòng)注入,指定注入哪個(gè)名稱的對象
    @Resource(name = "dog")
    private Dog dog;
  1. @Autowired 自動(dòng)裝配
    問題:如果發(fā)現(xiàn)多個(gè)類型一致的對象,將無法選擇具體注入哪一個(gè)對象
    如果需要指定注入某一個(gè)對象,需要添加輔助注解

在User 中只需要添加注解

    @Autowired
    @Qualifier("dog2")
    private Dog dog;

2.4 創(chuàng)建和銷毀注解

@PostConstruct // 在對象創(chuàng)建后調(diào)用,相當(dāng)于init-method
    public void init() {
        System.out.println("初始化方法調(diào)用");
    }

    @PreDestroy // 在對象銷毀之前調(diào)用,相當(dāng)于destroy-method
    public void destroy() {
        System.out.println("銷毀方法調(diào)用");
    }

3. spring junit整合測試

這樣就不需要在每個(gè)測試方法中都重復(fù)書寫獲取對象的代碼

// 幫我們創(chuàng)建容器
@RunWith(SpringJUnit4ClassRunner.class)

// 指定創(chuàng)建容器使用哪一個(gè)配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class Test02 {

    @Resource(name = "user")
    private User user;

    @Test
    public void testFunc01() {

        System.out.println(user);
    }
}

4. spring aop

4.1 aop 名詞

  1. Joinpoint(連接點(diǎn)):目標(biāo)對象中,所有可以增強(qiáng)的方法。(可以增強(qiáng)的方法)

  2. Pointcut(切入點(diǎn)):目標(biāo)對象中,已經(jīng)被增強(qiáng)的方法。(已經(jīng)增強(qiáng)的方法)

  3. Advice(通知/增強(qiáng)):增強(qiáng)的代碼。(例如:打開事務(wù),關(guān)閉事務(wù))

  4. Target(目標(biāo)對象):被代理對象

  5. Weaving(織入):將通知應(yīng)用到連接點(diǎn)的過程

6.Proxy(代理):將通知織入到目標(biāo)對象之后,形成代理對象

7.Aspect(切面):切入點(diǎn)+通知

4.2 配置將通知織入目標(biāo)對象

  1. 準(zhǔn)備一個(gè)通知類
/// 通知類
public class MyAdvice {
    public MyAdvice() {
    }

    // 前置通知 -》目標(biāo)方法調(diào)用之前調(diào)用
    public void before() { System.out.println("這是前置通知"); }

    // 后置通知(如果出現(xiàn)異常不會調(diào)用)-》在目標(biāo)方法調(diào)用之后調(diào)用
    public void afterReturning() { System.out.println("這是后置通知"); }

    // 環(huán)繞通知 -》在目標(biāo)方法調(diào)用之前和之后都調(diào)用
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        // 調(diào)用目標(biāo)方法
        System.out.println("這是環(huán)繞通知前部分");
        Object proceed = pjp.proceed();
        System.out.println("這是環(huán)繞通知后部分");
        return proceed;
    }

    // 異常攔截通知 -》如果出現(xiàn)異常會調(diào)用
    public void afterException() {
        System.out.println("這是異常攔截通知");
    }

    // 后置通知(如果出現(xiàn)異常仍會調(diào)用)-》在目標(biāo)方法調(diào)用之后調(diào)用
    public void after() {
        System.out.println("這是后置通知-出現(xiàn)異常仍會調(diào)用");
    }

}
  1. 配置通知對象和通知方法
 <!--配置目標(biāo)對象-->
    <bean name="userService" class="service.UserServiceImpl"></bean>

    <!--配置通知對象-->
    <bean name="myAdvice" class="springAop.MyAdvice"></bean>

    <!--配置將通知織入目標(biāo)對象-->
    <!--
        public void service.UserServiceImpl.save()
        void service.UserServiceImpl.save()
        * service.UserServiceImpl.*()
        * service.*ServiceImpl.*(..)
    -->
    <aop:config>
        <aop:pointcut expression="execution(* service.*ServiceImpl.*(..))" id="pc"/>

        <aop:aspect ref="myAdvice" >
            <!-- 指定名為before方法作為前置通知 -->
            <aop:before method="before" pointcut-ref="pc" />
            <!-- 后置 -->
            <aop:after-returning method="afterReturning" pointcut-ref="pc" />
            <!-- 環(huán)繞通知 -->
            <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>

3.進(jìn)行測試

// 幫我們創(chuàng)建容器
@RunWith(SpringJUnit4ClassRunner.class)
// 指定創(chuàng)建容器使用哪一個(gè)配置文件
@ContextConfiguration("classpath:springAop/applicationContext.xml")
public class Test03 {

    @Resource(name = "userService")
    private UserService us;

    @Test
    public void testFunc01() {

        us.save();
    }
}
  1. 結(jié)果輸出


    Snip20180802_16.png

4.3 使用注解配置 將通知織入目標(biāo)對象

1.在配置文件中開啟自動(dòng)代理

<aop:aspectj-autoproxy/>

2.在通知類中進(jìn)行配置

/// 通知類
@Aspect
public class MyAdvice {

    @Pointcut("execution(* service.UserServiceImpl.*(..))")
    public void pc() {}

    // 前置通知 -》目標(biāo)方法調(diào)用之前調(diào)用
    @Before("MyAdvice.pc()")
    public void before() { System.out.println("這是前置通知"); }

    // 后置通知(如果出現(xiàn)異常不會調(diào)用)-》在目標(biāo)方法調(diào)用之后調(diào)用
    @AfterReturning("MyAdvice.pc()")
    public void afterReturning() { System.out.println("這是后置通知 (如果出現(xiàn)異常不會調(diào)用)"); }

    // 環(huán)繞通知 -》在目標(biāo)方法調(diào)用之前和之后都調(diào)用
    @Around("MyAdvice.pc()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        // 調(diào)用目標(biāo)方法
        System.out.println("這是環(huán)繞通知前部分");
        Object proceed = pjp.proceed();
        System.out.println("這是環(huán)繞通知后部分");
        return proceed;
    }

    // 異常攔截通知 -》如果出現(xiàn)異常會調(diào)用
    @AfterThrowing("MyAdvice.pc()")
    public void afterException() {
        System.out.println("這是異常攔截通知");
    }

    // 后置通知(如果出現(xiàn)異常仍會調(diào)用)-》在目標(biāo)方法調(diào)用之后調(diào)用
    @After("MyAdvice.pc()")
    public void after() {
        System.out.println("這是后置通知(如果出現(xiàn)異常仍會調(diào)用)");
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容