본문 바로가기

IT공부/SPRING

스프링 4회차.

생성자 주입방식 <constructor-arg>/


springbasic 프로젝트 우클릭하여 properties에서 Project Facets에 들어가서

Dynamic Web Module 3.1버전으로 설정(설정 저장이 안되서2.3버전으로 사용)

Java 1.8버전



springbagic 프로젝트에 Java Resources안에 src/main/java안에 패키지생성을 해준다

kr.or.nextit/board

kr.or.nextit/member

kr.or.nextit/member/dao

kr.or.nextit/member/service


이렇게 패키지 생성을 하였고


첫번째로 dao 패키지안에 MemberDao 클래스를 생성했다.


두번째로 service안에 MemberService인터페이스를 생성하고 MemberServiceImpl클래스를 같이 생성했다.


MemberService에서 

public void getMember();


MemberServiceImpl에서 getMember를 오버라이즈 해준다.

public class MemberServiceImpl implements MemberService {


@Override public void getMember() {      }

}

다음으로 MemberDao에서 아래와 같이 작성한후

public void selectMember() { System.out.println("[MemberDao] selectMember() 실행..."); }

MemberServiceImpl에서 아래처럼 추가 수정해줬다.

private MemberDao memberDao; @Override public void getMember() { System.out.println("[MemberServiceImpl] getMember() 실행..."); memberDao.selectMember(); }

다음으로 MemberServiceImpl에서 memberdao를 받아온다.

private MemberDao memberDao; public MemberServiceImpl(MemberDao memberDao) { this.memberDao = memberDao; } @Override public void getMember() { System.out.println("[MemberServiceImpl] getMember() 실행..."); memberDao.selectMember(); }

이후로 kr.or.nextit에 메인클래스를 생성해준다.

클래스 이름은 NonSpringMain으로 스프링 사용하지않고 직접 객체생성에 관여하는 방법으로 했다.

public static void main(String[] args) {     // 객체를 직접 생성했고 서비스로 직접 넘겨준다

MemberDao memberDao = new MemberDao(); MemberService memberService = new MemberServiceImpl(memberDao); memberService.getMember();

}


이번엔 스프링을 사용하는 방법인데 직접 객체생성에 관여하지 않는다.

springbasic/src/main/resources안에 Spring Bean Configuration File 형식으로 

application-context.xml라는 파일을 생성해준다.

<!-- Constructor 주입방식 -->

<!-- 빈 생성 --> <bean id="memberService" class="kr.or.nextit.member.service.MemberServiceImpl">

<!-- id는 서비스 변수명과 같아야하고 서비스 내에 디폴트 생성자가 있어야한다. -->     <constructor-arg> <ref bean="memberDao"/>     </constructor-arg> </bean> <!-- new MemberDao() --> <bean id="memberDao" class="kr.or.nextit.member.dao.MemberDao"></bean>


위처럼 작성이후 NameSpaces탭에서 아래와같이 체크해준뒤 저장해준다.



kr.or.nextit패키지 안에 SpringDIMain클래스를 생성.

public static void main(String[] args) {     // 컨텍스트 생성     AbstractApplicationContext context =

new GenericXmlApplicationContext("classpath:application-context.xml");

// MemberService memberService = (MemberService)context.getBean("memberService");

// 캐스팅해줘도되나 아래것을 사용하자.

MemberService memberService = context.getBean("memberService", MemberService.class); memberService.getMember(); // 선택사항이지만.... 닫아주자. context.close();

}

제대로 생성이 되는지 확인을 위해 MemberServiceImpl에서 콘솔을 찍어준다.

public MemberServiceImpl(MemberDao memberDao) {     System.out.println("MemberServiceImpl : memberDao 주입 성공...");    <---이것만 추가.     this.memberDao = memberDao; }

같은 의미로 MemberDao에도 콘솔을 찍어주자.

public MemberDao() { System.out.println("MemberDao 객체 생성..."); }

여기까지가 Constructor Injection 방식이다.


Setter Injection 방식으로 해보자.

application-context.xml에서 Setter Injection방식으로 새로 해보자. 기존 Constructor는 주석처리.

<bean id="memberService" class="kr.or.nextit.member.service.MemberServiceImpl"> <property name="memberDao" ref="memberDao"/><!-- setMemberDao로 바꿔서 찾아주기때문에 setter가 꼭 필요하다. --> </bean> <!-- new MemberDao() --> <bean id="memberDao" class="kr.or.nextit.member.dao.MemberDao"></bean>

MemberServiceImpl클래스에 setMemberDao를 생성해준다.

public void setMemberDao(MemberDao memberDao) {

System.out.println("MemberServiceImpl Setter : memberDao 주입 성공..."); this.memberDao = memberDao;

}


위처럼 application-context.xml을 작성해줄수도 있지만 좀더 간단하게 내용을 바꿀수있다.

<!-- 속성값으로도 줄수있는데 p:memberDao="문자열"로 줄수도 있지만 ref를 붙여 p(property)를 속성으로 줌으로 한줄로 끝낼수도 있다. --> <bean id="memberService" class="kr.or.nextit.member.service.MemberServiceImpl" p:memberDao-ref="memberDao" /> <bean id="memberDao" class="kr.or.nextit.member.dao.MemberDao"></bean>


autowire를 이용하면 위에 p(property)를 이용하는것보다 손쉽게 이용가능.(자동으로 엮어주기때문에)

<!-- autowire는 자동으로 엮어준다. 타입으로 줄때는 byType(충돌될 가능성이 있음), 이름은 byName(유일하기때문에 사용에 좀더 적절하다) --> <bean id="memberService" class="kr.or.nextit.member.service.MemberServiceImpl" autowire="byName"/> <bean id="memberDao" class="kr.or.nextit.member.dao.MemberDao"></bean>


Spring Bean의 기본 Scope는 singleton인데 Spring IoC Container 내에 단하나의 객체만 존재하는걸 singleton이라 한다.

다수를 쓰기위해서는 Scope를 prototype으로 설정해주면 여러개의 객체가 존재하게 할수있다.





패키지 생성을 해준다

kr.or.nextit.board.controller 생성후 BoardController 클래스를 생성한다

kr.or.nextit.board.dao 생성후 BoardDao 클래스를 생성한다

kr.or.nextit.board.service 생성후 BoardServiceImpl 클래스를 생성하고 BoardService인터페이스를 생성해준다.



application-context.xml을 복사해서 application-anno-context.xml로 네이밍 해준뒤 기존 내용은 지워준다.

<!-- annotation 기반으로 빈 설정. --> <context:annotation-config/>     <bean id="boardController" class="kr.or.nextit.board.controller.BoardController"></bean>     <bean id="boardService" class="kr.or.nextit.board.service.BoardServiceImpl"></bean>     <bean id="boardDao" class="kr.or.nextit.board.dao.BoardDao"></bean>

BoardDao가 잘 돌아가는지 콘솔을 찍어준다.

public void selectBoard() {     System.out.println("[BoardDao] selectBoard() 실행..."); }

BoardService

public void getBoard();

BoardServiceImpl(필드에 오토와이드를 주면 아래것들도 한번에 잡힌다)

@Autowired private BoardDao boardDao; //    @Autowired // setter만 사용 가능 //    public void setBoardDao(BoardDao boardDao) { //        System.out.println("[BoardServiceImpl] Setter 주입완료..."); //        this.boardDao = boardDao; //    } //    @Autowired //    public BoardServiceImpl(BoardDao boardDao) { //        System.out.println("[BoardServiceImpl] 생성자 주입완료..."); //        this.boardDao = boardDao; //    } public BoardServiceImpl () {} @Override public void getBoard() {     System.out.println("[BoardServiceImpl getBoard() 실행..."); boardDao.selectBoard();     } }


SpringDIAnnoMain

public static void main(String[] args) {     // 컨텍스트 생성     AbstractApplicationContext context = new GenericXmlApplicationContext("classpath:application-anno-context.xml"); //    MemberService memberService = (MemberService)context.getBean("memberService"); // 캐스팅해줘도되나 아래것을 사용하자. //    BoardService boardService = context.getBean("boardService", BoardService.class); //    boardService.getBoard();     BoardController boardController = context.getBean("boardController", BoardController.class);     boardController.getBoard();

    context.close(); }

BoardController(Autowired는 자동으로 잡아주지만 Resource는 이름을 넣어줘야한다.)

//@Autowired @Resource(name="boardService") private BoardService boardService; public void getBoard() {     System.out.println("[BoardController] getBoard() 실행...");     boardService.getBoard(); }


빈 스캔(Bean을 자동으로 검색해서 등록해준다)은 아래처럼 기존내용에 추가만 해주면 된다.)

기존 application-anno-context.xml에서 <bean id="">으로 컨트롤러, 서비스, 다오 등 일일히 등록해주는부분도 한줄 처리가 가능하다. 


<!-- 빈 스캔. @Component(상위-통틀어서 component라고함),

@Controller, @Service, @Repository(Dao), <context:annotation-config/> 자동 등록-->

<context:component-scan base-package="kr.or.nextit"></context:component-scan>

BoardController는 맨위에 @Controller

@Controller public class BoardController {     //@Autowired     @Resource(name="boardService")     private BoardService boardService;     public void getBoard() {         System.out.println("[BoardController] getBoard() 실행..."); boardService.getBoard();     } }

BoardDao는 맨위에 @Repository를 달아준다.

@Repository public class BoardDao {     public void selectBoard() {         System.out.println("[BoardDao] selectBoard() 실행...");     } }

BoardServiceImpl에서 주의할점은 주석에도 달아놨지만

@Service만 주면안된다는것이다.

이때 @Service만 주면 boardServiceImpl이 자동으로 잡히기때문에 인터페이스에서 줬던 이름인 boardService로 이름을 설정해줘야한다. 

@Service("boardService")

// 이름을 안주면 boardServiceImpl로 들어감 이름을 BoardService로 줫기때문에 별도로 이름을 부여해준다.

// 이름은 인터페이스를 기준으로 주도록 하자. public class BoardServiceImpl implements BoardService{ @Autowired // 역할이 다르다 DI등록용 private BoardDao boardDao; // @Autowired // setter만 사용 가능 // public void setBoardDao(BoardDao boardDao) { // System.out.println("[BoardServiceImpl] Setter 주입완료..."); // this.boardDao = boardDao; // } // @Autowired // public BoardServiceImpl(BoardDao boardDao) { // System.out.println("[BoardServiceImpl] 생성자 주입완료..."); // this.boardDao = boardDao; // } public BoardServiceImpl () {} @Override public void getBoard() { System.out.println("[BoardServiceImpl getBoard() 실행..."); boardDao.selectBoard(); } }














'IT공부 > SPRING' 카테고리의 다른 글

SpringMVC  (0) 2019.08.09
DI AOP MVC  (0) 2019.08.09
BoardDao를 BoardMapper로 바꿔준다.  (0) 2019.08.05
mybatis에서 로그를 보기위해 Log4j 설치하기.  (0) 2019.08.05
스프링 2회차.  (0) 2019.08.05