본문 바로가기
kosta/Spring

Spring 기초(실습)

by 엑츄얼리 2022. 5. 12.

프로젝트 생성 방법 및 Maven 설정(pom.xml)

https://k39335.tistory.com/70 

 

[Spring] IntelliJ에서 Spring + Maven 프로젝트 생성하기

[Spring] IntelliJ에서 Spring + Maven 프로젝트 생성하기 이번 포스팅의 목표는 IntelliJ를 이용하여 Spring + Maven 프로젝트를 생성하고, 실행 가능한 상태까지 만드는 것이 목표이다. 프로젝트 구조 구성이

k39335.tistory.com

 

 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.kosta.spring</groupId>
    <artifactId>Kosta_Spring_Maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.20.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.20.RELEASE</version>
        </dependency>

    </dependencies>
</project>

 

 

실습

DI

 - 기본적으로 프로그램 실행 순서에 따라서 파일을 기입하였으며, 과정에서 생략된 파일은 이전 과정과 같다.

1. applicationContext.xml - 명시적

 1) applicationContext.xml construct-arg 방식

resources/applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="oracleDao" class="kosta.di.OracleDao"/>
    <bean id="MySQLDao" class="kosta.di.MySQLDao"/>

    <bean id="service" class="kosta.di.WriteService">
        <!--1. constructor-arg는 생성자를 통해 객체(ref)를 전달-->
        <constructor-arg ref="oracleDao"></constructor-arg>
    </bean>
</beans>

 

kosta.di/main.java

package kosta.di;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("applicationContext.xml");

        BeanFactory factory = new GenericXmlApplicationContext(resource);

        Service service = (Service)factory.getBean("service");
        service.insert();
    }
}

 

kosta.di/WriteService.java

package kosta.di;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("applicationContext.xml");

        BeanFactory factory = new GenericXmlApplicationContext(resource);

        Service service = (Service)factory.getBean("service");
        service.insert();
    }
}

 

kosta.di/OracleDao.java

package kosta.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

public class OracleDao implements Dao{
    @Override
    public void insertBoard() {
        System.out.println("OracleDao insertBoard() 호출");
    }
}

 

kosta.di/MySQLDao.java

package kosta.di;

import org.springframework.stereotype.Repository;

public class MySQLDao implements Dao{
    @Override
    public void insertBoard(){
        System.out.println("MySQLDao insertBoard() 호출");
    }
}

 

 

 

 2) applicationContext.xml - property 방식

같은 interface를 공유하는 객체가 여러개 존재할 경우 필요

 

applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="oracleDao" class="kosta.di.OracleDao"/>
    <bean id="MySQLDao" class="kosta.di.MySQLDao"/>

    <bean id="service" class="kosta.di.WriteService">
<!--property 는 set{Name}메서드를 통해 객체(ref)를 전달-->
        <property name="Dao" ref="oracleDao"/>
        <property name="Dao2" ref="MySQLDao"/>
    </bean>
</beans>

 

WriteService.java

package kosta.di;

public class WriteService implements Service{

    private Dao dao;

    @Override
    public void insert() {
        System.out.println("WriteService insert 호출");
        dao.insertBoard();
    }

    public void setDao(Dao dao) {
        System.out.println("setDao");
        this.dao = dao;
    }

    public void setDao2(Dao dao2) {
        System.out.println("setDao2");
        this.dao = dao2;
    }
}

 

* 잘 모르겠는 부분

main.java의 이부분을 디버그 시

BeanFactory factory = new GenericXmlApplicationContext(resource);

 

 아래의 매서드(Spring 내부)에서 property들이 초기화됨을 확인할 수 있었다.

thisefresh 부분에서 property들이 초기화된다.

 

main 실행 시 출력

 

2. applicationContext.xml - 자동

1) 기본(?)

applicationContext.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: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
       https://www.springframework.org/schema/context/spring-context.xsd">

<!--자동    -->
<!--beans에 xmlns:context 추가 및 schemaLocation에 경로 추가 (자동으로 되는데 안될 때도 있음)-->
        <context:component-scan base-package="kosta.di"/>
</beans>

 

main.java

package kosta.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("applicationContext.xml");

        ApplicationContext factory =
                new GenericXmlApplicationContext(resource);

        Service service = (Service)factory.getBean("writeService");
        service.insert();
    }
}

 

WriteService.java

package kosta.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@org.springframework.stereotype.Service
public class WriteService implements Service{

    @Autowired
    @Qualifier("mySQLDao")
    private Dao dao;

    @Override
    public void insert() {
        System.out.println("WriteService insert 호출");
        dao.insertBoard();
    }
}

 

OracleDao.java

package kosta.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class OracleDao implements Dao{
    @Override
    public void insertBoard() {
        System.out.println("OracleDao insertBoard() 호출");
    }
}

 

MySQLDao.java

package kosta.di;

import org.springframework.stereotype.Repository;

@Repository
public class MySQLDao implements Dao{
    @Override
    public void insertBoard(){
        System.out.println("MySQLDao insertBoard() 호출");
    }
}

 

2) Factory.java를 통해 Bean 객체를 반환

 - Factory.java를 통해 이전에 @Repository를 통해 생성했던 객체를 생성

    (이 부분에서는 OracleDao.java와 MySQLDao.java의 @Repository 를 삭제)

Main.java

package kosta.di;


import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args) {
        ApplicationContext factory =
                new AnnotationConfigApplicationContext(Factory.class);
        Service service = (Service)factory.getBean("writeService");
        service.insert();
    }
}

 

Factory.java

package kosta.di;

import org.springframework.context.annotation.Bean;

public class Factory {
    @Bean
    public Dao oracleDao(){
        return new OracleDao();
    }

    @Bean public Service writeService(){
        return new WriteService();
    }
}

 

WriteService.java

package kosta.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@org.springframework.stereotype.Service
public class WriteService implements Service{

    @Autowired
    private Dao dao;

    public WriteService() {
    }

    public WriteService(Dao dao) {
        this.dao = dao;
    }

    @Override
    public void insert() {
        System.out.println("WriteService insert 호출");
        dao.insertBoard();
    }

    public void setDao(Dao dao) {
        this.dao = dao;
    }

    public void setDao2(Dao dao2) {
        this.dao = dao;
    }
}

 

 

AOP

Main.java

package kosta.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        String configLocations[] = {
                "applicationContext.xml",
                "commonConcern.xml"
        };

        ApplicationContext factory = new ClassPathXmlApplicationContext(configLocations);

        Service service = (Service)factory.getBean("writeService");
        service.insert();//공통 관심사항 메서드도 함께 출력
    }
}

 

 

commonConcern.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="logAspect" class="kosta.aop.LoggingAspect"/>
    
    <aop:config>
        <aop:pointcut expression="execution(public * kosta..*Service.insert(..))" id="servicePointCut"/>

        <aop:aspect id="loggingAspect" ref="logAspect">
            <aop:around method="logging" pointcut-ref="servicePointCut"/>
        </aop:aspect>

    </aop:config>
</beans>

 

LoggingAspect.java

package kosta.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;

//공통관심사항
public class LoggingAspect {
    //핵심비지니스 메서드호출 => 메서드 호출 시간을 측정
    //타이머 작동 -> 메서드 호출 -> 타이머 종료 -> 시간을 출력

    private Log log = LogFactory.getLog(getClass());

    //공통 관심메서드 정의
    //내용 : 핵심관심메서드 호출 시 시간 측정
    //advice : 이전(공통) -> 핵심메서드(insert()) -> 이후(공통) : around (ProceedingJoinPoint)

    public Object logging(ProceedingJoinPoint joinPoint) throws Throwable{
        log.info("로그 시작");
        StopWatch stopWatch = new StopWatch();

        try{
            stopWatch.start();

            //핵심 관심메서드 호출:WriteService insert()호출
            Object obj = joinPoint.proceed();

            return obj;
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            stopWatch.stop();
            log.info("종료");
            log.info(joinPoint.getSignature().getName() + "메서드 실행 시 : " + stopWatch.getTotalTimeMillis());
        }

        return null;
    }
}

 

OracleDao.java

package kosta.di;

import org.springframework.stereotype.Repository;

@Repository
public class OracleDao implements Dao{
    @Override
    public void insertBoard() {
        System.out.println("OracleDao insertBoard() 호출");
    }
}

 

출력

 

'kosta > Spring' 카테고리의 다른 글

@ModelAttribute 추가 이해  (0) 2022.06.14
Maven 기반 Spring 프로젝트 생성!  (0) 2022.05.18
Spring 기초3(실습)  (0) 2022.05.18
Spring 기초2(실습)  (0) 2022.05.16

댓글