spring 입문 및 상용 주해 사용

21609 단어 spring
현재 자바 주류 의 오픈 소스 프레임 워 크 는 ssh 든 ssi 든 spring 을 제외 한 다른 프레임 워 크 는 모두 교체 가능 한 프레임 워 크 struts 2 와 springmvc,hibenate 와 ibatis(my batis)가 있 습 니 다.여기 서 우 리 는 다른 프레임 워 크 의 우열 을 토론 하지 않 습 니 다.그런데 왜 spring 은 개발 자 들 에 게 인기 가 많 습 니까?그것 이 바로 스프링 의 장점 이다.블 로 거들 은 스프링 의 장점 이 다음 과 같다 고 생각한다.
1.경량급:원 하 는 서 비 스 를 선택 할 수 있 고 코드 의 저 침입 성 을 선택 할 수 있 습 니 다.
2.반전 제어 ioc:Spring 은 제어 반전 기술 로 소나무 결합 을 실현 했다.의존 대상 을 만 들 거나 찾 는 것 이 아니 라 대상 에 주입 된다.
3.절단면 프로 그래 밍 op:Spring 은 절단면 프로 그래 밍 을 지원 하 는 동시에 응용 업무 논리 와 시스템 서 비 스 를 분리 합 니 다.
4.사무 관리:spring 은 강력 한 사무 처리 능력 을 가지 고 있 습 니 다.
5.집적 성:다른 프레임 을 잘 집적 할 수 있다.
그러면 저희 가 코드 를 결합 해서 스프링 의 각 점 을 차례대로 말씀 드 리 겠 습 니 다.
경량급

	4.0.0

	com.julyday
	myspring
	0.0.1-SNAPSHOT
	jar

	myspring
	http://maven.apache.org

	
		UTF-8
		4.1.4.RELEASE
	

	
		
			junit
			junit
			4.12
			test
		

		
		
			org.springframework
			spring-core
		

		
			org.springframework
			spring-beans
		

		
			org.springframework
			spring-context
		
	
	
		
			
				org.springframework
				spring-framework-bom
				${spring.version}
				pom
				import
			
		
	



위 에는 우리 가 필요 로 하 는 spring 모듈 이 있 습 니 다.세 개 만 있 습 니 다.jar 가방 을 다시 보 겠 습 니 다.Junit 4 를 포함 하여 모두 9 개의 jar 가방 이 있 습 니 다.우아 하지 않 습 니까?
2.반전 제어 ioc
OK,다음은 블 로 거들 이 밥 을 사 는 것 으로 스프링 의 간단 한 예 를 들 어 보 겠 습 니 다.
먼저 밥 을 살 때 사람 을 적 게 받 지 않 는 다.우 리 는 인간 의 인 터 페 이 스 를 만 들 었 다.
public interface Person {

	public void eat();
	
}

다음은 작가 본인 과 같은 부류 이다.
public class Author implements Person {
	
	@Override
	public void eat() {
		System.out.println("      ");
	}
	
}

spring-bean.xml 를 만 듭 니 다.다음 과 같 습 니 다.


        
        
     

테스트 아래:
BeanTest.java:
package com.julyday.myspring;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

@RunWith(BlockJUnit4ClassRunner.class)
public class BeanTest extends BaseTest{
	
	@Test
	public void testBean(){
		Person author = (Person)context.getBean("author");
		author.eat();
	}
}

BaseTest.java:
package com.julyday.myspring;

import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BaseTest {
	public ClassPathXmlApplicationContext context;
	
	@Before
	public void before() {
		try {
			context = new ClassPathXmlApplicationContext("spring-bean.xml");
			context.start();
		} catch (BeansException e) {
			e.printStackTrace();
		}
	}
	
	@After
	public void after() {
		context.destroy();
	}
}

testBean 방법 을 선택 하고 Junit Test 를 오른쪽 단추 로 실행 하 였 습 니 다.실행 에 성 공 했 습 니 다.
작 가 는 혼자 밥 을 먹 는 것 이 재미 없어 서 다른 친 구 를 찾 아 함께 왔 다.
첫 번 째 는 미국인 이다.
public class American implements Person{

	@Override
	public void eat() {
		System.out.println("        ");
	}

}

...에 있다
spring-bean.xml beans 에 추가:
여기에 scope 를 추 가 했 습 니 다.쉽게 말 하면 이 표 지 를 추가 하지 않 은 것 은 singleton(단일 사례)입 니 다.
prototype 이것 은 매번 요청(다른 bean 에 주입 되 거나 spring 용기 의 getBean()방법 포함)입 니 다.
물론 웹 프로젝트 에 도 있어 요.
request(http 요청 하나),
session(한 번 session 답장 하나),
global session(표준 HTTP Session 역할 영역 과 같 지만 portlet 기반 웹 응용 에서 만 의미 가 있 습 니 다).
대부분의 경우 우 리 는 여전히 하나의 예 를 사용한다.
다음은 테스트 클래스 테스트 를 만 들 겠 습 니 다.
ScopeTest.java
@RunWith(BlockJUnit4ClassRunner.class)
public class ScopeTest extends BaseTest{
	
	@Test
	public void testBean(){
		Person p1 = (Person)context.getBean("author");
		p1.eat();
		Person p2 = (Person)context.getBean("author");
		p2.eat();
		System.out.println(p1.hashCode());
		System.out.println(p2.hashCode());
		
		
		Person p3 = (Person)context.getBean("american");
		p3.eat();
		Person p4 = (Person)context.getBean("american");
		p4.eat();
		System.out.println(p3.hashCode());
		System.out.println(p4.hashCode());
		
	
	}
}

운영 결과 에 따 르 면 작 가 는 이 한 곳 에 만 지점 이 없고 작가 의 미국 친 구 는 많다.
저 자 는 또 친구 zhangsan 과 lisi 가 있 습 니 다.
public class Zhangsan implements Person {

	public void init(){
		System.out.println("Zhangsan       ");
	}
	
	@Override
	public void eat() {
		System.out.println("Zhangsan     ");
	}
	
	public void destroy(){
		System.out.println("Zhangsan     ");
	}

}
public class Lisi implements Person {

	public void init(){
		System.out.println("Lisi       ");
	}
	
	@Override
	public void eat() {
		System.out.println("Lisi      ");
	}
	
	public void destroy(){
		System.out.println("Lisi   ");
	}
}

spring-bean.xml beans 에 추가:
 
 
테스트 아래:
LazyTest.java
public class LazyTest extends BaseTest {
	@Test
	public void testBean(){
//		Zhangsan zhangsan = (Zhangsan)context.getBean("zhangsan");
//		zhangsan.eat();
		Lisi lisi = (Lisi)context.getBean("lisi");
		lisi.eat();
	}
}	

장 삼 은 처음에 오지 않 았 다.우 리 는 운행 하 다가 마치 spring 이 장 삼 을 오 게 한 것 처럼 비 과학적 이 었 다.하지만 자세히 보 니 장 삼 은 eat 가 없 군요.여기 서 spring 관리 bean 의 로드 메커니즘 을 말씀 드 리 겠 습 니 다.기본 적 인 것 은 용기 가 시 작 될 때 spring 이 모든 것 을...
하나의 bean 이 모두 만 들 어 졌 기 때문에 spring 은 초기 화 방법 init 를 호출 했 고 용기 가 꺼 졌 을 때 destroy 방법 을 사용 했다.
프로 토 타 입 이 라면 이 럴 까요?동료 들 은 스스로 해 볼 수 있다.
이상 의 간단 한 예 를 우 리 는 다시 주해 의 방식 으로 한 번 실현 한다.
우선 spring-beanannotation.xml 을 쓰 십시오.



	
	
	


다른 종류의 주 해 는 다음 과 같 습 니 다.(비교 하기 편리 하도록 가방 com.july day.my spring.annotation 을 새로 만 들 었 습 니 다)
@Component
@Scope("prototype")
public class American implements Person{
	
	@Override
	public void eat() {
		System.out.println("        ");
	}
}
@Component
public class Author implements Person{

	@Override
	public void eat() {
		System.out.println("      ");
	}
	
}
@Component
public class Lisi implements Person{
	
	@PostConstruct
	public void init(){
		System.out.println("Lisi       ");
	}
	
	@Override
	public void eat() {
		System.out.println("Lisi      ");
	}
	
	@PreDestroy
	public void destroy(){
		System.out.println("Lisi   ");
	}
}
@Lazy(false)
@Component
public class Zhangsan implements Person{
	
	@PostConstruct
	public void init(){
		System.out.println("Zhangsan       ");
	}
	
	@Override
	public void eat() {
		System.out.println("Zhangsan     ");
	}
	
	@PreDestroy
	public void destroy(){
		System.out.println("Zhangsan     ");
	}
}

알 겠 습 니 다.BaseTest.java 에 있 는 before 방법 context 를 context=new ClassPathXmlapplicationContext("spring-beanannotation.xml")로 초기 화 합 니 다.
우리 의 테스트 를 다시 실행 하 는 것 은 방금 과 같다.분명히 세심 한 동료 가 블 로 거들 이 틀 렸 다 는 것 을 발견 했다!Lazy Test 라 는 테스트 클래스 의 결과 가 잘못 되 었 습 니 다.이것 은 당신 의 Lisi 클래스 의 경로 가 잘못 되 었 기 때 문 입 니 다.게다가 import com.july day.my spring.annotation.Lisi;또는 테스트 클래스 도 com.july day.my spring.annotation 패키지 에 쓰 십시오.
@Component:spring 에 게 bean 이 라 고 말 해 주세요.
@Scope:bean 의 역할 영역 입 니 다.
@PostConstruct:bean 초기 화 방법.
@PreDestroy:bean 의 소각 방법.
@Lazy:bean 의 지연 로드 메커니즘,기본 값 은 true 입 니 다.
3.절단면 프로 그래 밍 op
다음은 세 가지 op 의 실현 을 설명 한다.
첫 번 째:api 방식
블 로 거들 은 밥 을 먹고 돌아 가 려 고 합 니 다.먼저 새로운 Person 인 터 페 이 스 를 만 듭 니 다.(op 가방 아래)
package com.julyday.myspring.aop;

public interface Person {
	
	public void back(String destination);
	
}

같은 블 로 거들
public class Author implements Person{

	@Override
	public void back(String destination) {
		System.out.println("    "+destination);
	}
	
}

블 로 거들 은 돌아 가기 전에 예의 바 르 게 친구 들 과 안녕 히 계 세 요.그러면 back 전에 spring 에 게 알려 야 합 니 다.
BeforeAdvice.java
public class BeforeAdvice implements MethodBeforeAdvice{

	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		System.out.println("      !");
		String argString = "";
		if(args.length > 0){
			for(Object obj : args){
				argString += obj.toString();
			}
		}
		System.out.println("BeforeAdvice before : method : "+method.getName() 
				+" args : "+argString+" target : "+target.getClass().getName());
	}

}

새 spring-aop-api.xml:


        
	
	
	
		
			
		
		
			com.julyday.myspring.aop.Person
		
		
			
				beforeAdvice
			
		
	

 

새 테스트 클래스
@RunWith(BlockJUnit4ClassRunner.class)
public class ApiTest extends BaseTest{
	@Test
	public void testApi(){
		Person p = (Person)context.getBean("author");
		p.back("  ");
	}
}
public class BaseTest {
	public ClassPathXmlApplicationContext context;
	
	@Before
	public void before() {
		try {
			context = new ClassPathXmlApplicationContext("spring-aop-api.xml");
			context.start();
		} catch (BeansException e) {
			e.printStackTrace();
		}
	}
	
	@After
	public void after() {
		context.destroy();
	}
}

블 로 거들 이 집에 돌아 오기 전에 스프링 은 블 로 거들 의 예의 바 르 게 before 방법 을 완성 했다.
블 로 거들 이 집에 돌아 갈 준 비 를 하고 있 는데 동료 샤 오 홍 은 블 로 거들 에 게 집 처럼 카드 놀 이 를 하 라 고 했다.
public class AroundAdvice implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("        666     ");
		Object obj = invocation.proceed();
		System.out.println("      ,        ");
		return obj;
	}

}

블 로 거들 이 카드 놀 이 를 하 러 가 려 고 할 때 아 내 는 나 에 게 집에 가서 영 화 를 보 여 달라 고 전 화 를 했다.
작성 자 수정
public class Author implements Person{

	@Override
	public void back(String destination) {
		System.out.println("    "+destination);
		throw new RuntimeException("              ");
	}
	
}
public class ThrowExAdvice implements ThrowsAdvice{
	
	public void afterThrowing(Exception ex) throws Throwable {
		System.out.println("ThrowExAdvice afterThrowing 1"+ex.getMessage());
	}
	
	public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
		System.out.println("ThrowExAdvice afterThrowing 2 : " + ex.getMessage());
	}
}

전반적 으로 블 로 거들 은 오늘 도 즐 거 웠 다.
전체 spring-op-api.xml 수정 은 다음 과 같 습 니 다.
public class AfterAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		System.out.println("            ");
	}

}
실행 중:


        
	
	
	
	
	
	
	
	
		
			com.julyday.myspring.aop.Person
		
		
			
			
		
		
			
				beforeAdvice
				afterAdvice
				aroundAdvice
				throwExAdvice
			
		
	

 
여기 서 주의해 야 할 것 은 프로그램 이 ThrowExAdvice 에 도착 하면 after Advice 는 실행 되 지 않 고 이상 이 없 으 면 after Advice 는 실 행 됩 니 다.
api 방식 소개 가 완 료 된 후에 xml 기반 설정 방식 을 살 펴 보 겠 습 니 다.
우선 pom.xml 증가:
4.567913.절단면 류 Author Aspect 가 추가 되 었 습 니 다.절단면 류 에는 여러 가지 통 하지 않 는 방법 이 있 습 니 다.
@RunWith(BlockJUnit4ClassRunner.class)
public class ApiTest extends BaseTest{
	@Test
	public void testApi(){
		Person p = (Person)context.getBean("author");
		p.back("   ");
	}
}
spring-aop-schema-advice.xml 파일 추가:
4
	
		org.springframework
		spring-aspects
	
두 개의 bean 은 더 이상 말 하지 않 습 니 다.config 에서 먼저 절단면 을 정의 하고 절단면 을 가리 키 는 bean 을 가리 키 며 절단면 에서 하나의 절 점 pointcut 을 정의 합 니 다.절 점 은 spring 에 게 그곳 에서 자 르 는 것 을 알려 주 는 것 입 니 다.그 다음 에 자 르 는 시기 입 니 다.
여기 expression="execution(*com.july day.my spring.aop.Author.*(...)"첫 번 째*는 모든 권한 수정자 가 일치 하 는 것 을 나타 낸다.이곳 은 더 이상 깊이 들 어가 지 않 는 다.
이어서 테스트 해 보 세 요:
package com.julyday.myspring.aop.schema;

import org.aspectj.lang.ProceedingJoinPoint;

public class AuthorAspect {

	public void before() {
		System.out.println("AuthorAspect before.");
	}

	public void afterReturning() {
		System.out.println("AuthorAspect afterReturning.");
	}

	public void afterThrowing() {
		System.out.println("AuthorAspect afterThrowing.");
	}

	public void after() {
		System.out.println("AuthorAspect after.");
	}

	public Object around(ProceedingJoinPoint pjp) {
		Object obj = null;
		try {
			System.out.println("AuthorAspect around 1.");
			obj = pjp.proceed();
			System.out.println("AuthorAspect around 2.");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return obj;
	}

}

4.567913.여기 서 지적 해 야 할 것 은 이상 이 발생 하면 뒤의 after 와 after Returning 은 계속 실 행 될 것 이 고 api 와 약간 다르다 는 것 이다.
세 번 째:주해 의 방식.



	
	
	
	
	
		
 			
			
			
			
			
			
		
	

 
package com.julyday.myspring.aop.schema;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

import com.julyday.myspring.aop.Person;

@RunWith(BlockJUnit4ClassRunner.class)
public class SchemaTest extends BaseTest{
	@Test
	public void testApi(){
		Person p = (Person)context.getBean("author");
		p.back("   ");
	}
}
spring-aop-aspectj.xml:
package com.julyday.myspring.aop.schema;

import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BaseTest {
	public ClassPathXmlApplicationContext context;
	
	@Before
	public void before() {
		try {
			context = new ClassPathXmlApplicationContext("spring-aop-schema-advice.xml");
			context.start();
		} catch (BeansException e) {
			e.printStackTrace();
		}
	}
	
	@After
	public void after() {
		context.destroy();
	}
}
테스트 아래:
package com.julyday.myspring.aop.aspectj;

import org.springframework.stereotype.Component;
import com.julyday.myspring.aop.Person;

@Component
public class Author implements Person {

	@Override
	public void back(String destination) {
		System.out.println("    "+destination);
		throw new RuntimeException("              ");
	}

}
package com.julyday.myspring.aop.aspectj;

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
@Aspect
public class AuthorAspect {
	
	@Pointcut("execution(* com.julyday.myspring.aop.aspectj.Author.*(..))")
	public void pointcut(){}
	
	@Before("execution(* com.julyday.myspring.aop.aspectj.Author.*(..))")
	public void before() {
		System.out.println("AuthorAspect before.");
	}
	
	@AfterReturning(value="pointcut()")
	public void afterReturning() {
		System.out.println("AuthorAspect afterReturning.");
	}
	
	@AfterThrowing("pointcut()")
	public void afterThrowing() {
		System.out.println("AuthorAspect afterThrowing.");
	}
	
	@After("pointcut()")
	public void after() {
		System.out.println("AuthorAspect after.");
	}

	@Around("pointcut()")
	public Object around(ProceedingJoinPoint pjp) {
		Object obj = null;
		try {
			System.out.println("AuthorAspect around 1.");
			obj = pjp.proceed();
			System.out.println("AuthorAspect around 2.");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return obj;
	}
}

이런 방식 과 xml 설정 방식 은 기본적으로 차이 가 많 지 않다.
네,스프링 의 간단 한 입문 은 여기까지 입 니 다.
마지막 으로 항목 의 모든 코드 를 올 립 니 다.
https://github.com/Julyday/myspring.git

좋은 웹페이지 즐겨찾기