1. 程式人生 > >spring Ioc的註解注入以及spring Aop的兩種配置方式

spring Ioc的註解注入以及spring Aop的兩種配置方式

1.spring Ioc的註解注入

    1.1 導包

        

    1.2 匯入約束

    

          

      1.3 選擇使用註解的包

            

      1.4 在類中使用註解配置bean

                User類

// <bean name="user" class="domain.User"></bean>
@Component("user")
/*@Service("user")//service層
@Controller("user")//web層
@Repository("user")//dao層
 */
//指定物件作用範圍
//@Scope(scopeName="prototype")
public class User {
@Value("mengyue")//為屬性注入值
private String name;
@Value("21")
private Integer age;

//@Autowired //自動裝配  多個物件時  無法選擇
//@Qualifier("car")  //告訴spring容器 裝配哪個名稱的物件
@Resource(name="car") //手動注入名稱為 car的物件
private Car car;

@PostConstruct //指明在構造方法之後呼叫該方法  相當於 init-method
public void init(){
System.out.println("我是初始化方法。");
}
@PreDestroy //指明在物件銷燬之前呼叫該方法 相當於 destory-method
public void destroy(){
System.out.println("我是銷燬方法。");
}
                Car類
@Component("car")
public class Car {
	@Value("法拉利488")
	private String name;
	@Value("白色")
	private String color;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public Car() {
	}
	public String toString() {
		return "Car [name=" + name + ", color=" + color + "]";
	}
	
}
            測試類
//建立容器
/*@RunWith(SpringJUnit4ClassRunner.class)  
//指定建立容器時載入哪個配置檔案
@ContextConfiguration("classpath:applicationContext.xml")*/
public class demo {
	/*@Resource(name="user")
	private User u;*/
	@Test
	public void test1(){
		ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
		User user=(User) applicationContext.getBean("user");
		System.out.println(user);
		
	}

               執行結果

2.spring Aop

    2.1 spring Aop的介紹

            Aop是一種面向切面程式設計的思想,將重複的程式碼 抽取出來 切入到流程當中。spring 實現Aop的原理是運用了動態代理和cglib代理。動態代理是JDK自帶的代理技術,要求被代理物件必須要實現介面,才能產生代理物件,如果沒有介面,就不能使用動態代理技術。cglib是一種第三方代理技術,可以對任何類生成代理,cglib進行代理的原理是,對目標物件進行繼承,所以當目標物件被final修飾時,該類無法被代理。

            在選擇上,spring會優先選擇動態代理,如果動態代理沒法滿足,就會採用cglib代理。

    Aop中的術語:Joinpoint(連線點) :目標物件可以被增強的方法

                             Pointcut(切入點):目標物件,需要增強的方法

                             Advice(通知):增強程式碼

                             Target(目標物件):被代理的物件

                              Weaving(織入):將通知織入切入點

                               Proxy(代理):完成織入之後,產生代理物件

                               aspect(切面):切入點+通知

2.2.spring Aop配置

       首先使用註解的方式配置

    2.2.1 導包

           

    2.2.2  匯入約束


     2.2.3 配置檔案

      

      2.2.4 目標物件

package service;

import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService{

	public void save() {
		System.out.println("增加使用者");
	}

	public void delete() {
		System.out.println("刪除使用者");
		
	}

	public void update() {
		System.out.println("修改使用者");
		
	}

	public void find() {
		System.out.println("查詢使用者");
		
	}
	

}

          2.2.5 通知

package aspects;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component("myAdvice")
// 告訴spring 該類為通知物件
@Aspect
public class MyAdvice {
	@Pointcut("execution(* service.*ServiceImpl.*(..))")
	public void pointCut(){}
	
	
	//指定前置通知  並指定切點
	@Before("MyAdvice.pointCut()")
	public void before(){
		System.out.println("這是前置通知!");
	}
	@AfterReturning("MyAdvice.pointCut()")
	public void afterReturning(){
		System.out.println("這是後置通知,丟擲異常時不執行!");
	}
	@Around("execution(* service.*ServiceImpl.*(..))")
	public Object around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("這是前置通知!");
		Object proceed = pjp.proceed();
		System.out.println("這是後置通知!");
		return proceed;
		
	}
	@AfterThrowing("execution(* service.*ServiceImpl.*(..))")
	public void exception(){
		System.out.println("有異常哦!");
	}
	@After("execution(* service.*ServiceImpl.*(..))")
	public void after(){
		System.out.println("這是後置通知,丟擲異常時依然執行!");
	}

}
            

             2.2.6 測試類

@Test
	public void test3(){
		ApplicationContext applicationContext= new ClassPathXmlApplicationContext("demo/applicationContext.xml");
		UserService userService=(UserService) applicationContext.getBean("userService");
		userService.find();
		
	}

    xml的方式進行配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.springframework.org/schema/beans" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
	<!--1.應用註解-->
	<context:component-scan base-package="domain"></context:component-scan>
	<!-- springAop的配置 -->
	<!-- 1.配置目標物件 -->
	<bean name="userService" class="service.UserServiceImpl"></bean>
	<!--2.配置通知物件 -->
	<bean name="myAdvice" class="aspects.MyAdvice"></bean>
	<!--3.將通知織入到目標物件  -->
	<aop:config>
		<!--3.1.配置切點  -->
		<aop:pointcut expression="execution(* service.*ServiceImpl.*(..))" id="pc"/>
		<!--3.2.配置切面 -->
		<aop:aspect ref="myAdvice">
			<aop:before method="before" pointcut-ref="pc"/>
			<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
			<aop:around method="around" pointcut-ref="pc"/>
			<aop:after-throwing method="exception" pointcut-ref="pc"/>
			<aop:after method="after" pointcut-ref="pc"/>
		</aop:aspect>
	</aop:config>
</beans>