반응형

Java Persistence API (일명 JPA)는 객체와 관계 데이터베이스 간의 데이터를 관리, 유지 및 액세스하기위한 Java 사양입니다. 최대 절전 모드는 JPA 사양을 구현하는 ORM (Object Relational Mapping) 도구입니다.

이 예에서는 Hibernate를 퍼시스턴스 제공자로 사용하여 Spring을 JPA와 통합하는 방법을 학습합니다.

이 응용 프로그램에 사용되는 도구 및 기술은 다음과 같습니다.

 

  • Spring 4.3.7.RELEASE
  • Hibernate 5.2.9.Final
  • JPA 2.1
  • MySQL Connector 6.0.5
  • MySQL Server 5.7.12
  • Eclipse Neon.3
  • Maven 3.3.9
  • JavaSE 1.8

Spring, Hibernate 및 JPA를 사용하여 간단한 독립형 애플리케이션을 작성해 봅시다.

프로젝트 구조

다음 maven 프로젝트 구조를 검토하십시오.

배우기-  이클립스에서 maven 프로젝트를 만드는 방법 .

Jar dependencies

pom.xml파일을 편집 하고 다음과 같이 Spring, Hibernate 및 MySQL 종속성을 추가 하십시오 .

pom.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<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.boraji.tutorial.hibernate</groupId>
  <artifactId>spring-hibernate-jpa-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>spring-hibernate-jpa-tutorial</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <!-- Spring Context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <!-- Spring ORM -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <!-- Mysql Connector -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>6.0.5</version>
    </dependency>
    <!-- Hibernate 5.2.9 Final -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.9.Final</version>
    </dependency>
    <!-- Apache Commons DBCP -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.1.1</version>
    </dependency>
  </dependencies>
 
  <build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
cs

JPA Entity class

다음과 같이 패키지 @Entity아래  클래스를  작성하십시오 com.boraji.tutorial.spring.entity.

Person.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.boraji.tutorial.spring.entity;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name = "PERSONS")
public class Person {
 
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
 
   @Column(name = "FIRST_NAME")
   private String firstName;
 
   @Column(name = "LAST_NAME")
   private String lastName;
 
   @Column(name = "EMAIL")
   private String email;
 
   public Person() {}
   
   public Person(String firstName, String lastName, String email) {
      this.firstName = firstName;
      this.lastName = lastName;
      this.email = email;
   }
 
   // Getter and Setter methods
}
cs

Data Access Object (DAO) class

다음과 같이 패키지 @Repository 아래에 클래스를  작성하십시오  com.boraji.tutorial.spring.dao.

PersonDao.java

 

1
2
3
4
5
6
7
8
9
10
package com.boraji.tutorial.spring.dao;
 
import java.util.List;
 
import com.boraji.tutorial.spring.entity.Person;
 
public interface PersonDao {
   void add(Person person);
   List<Person> listPersons();
}
cs

PersonDaoImp.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.boraji.tutorial.spring.dao;
 
import java.util.List;
 
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
 
import org.springframework.stereotype.Repository;
 
import com.boraji.tutorial.spring.entity.Person;
 
/**
 * @author imssbora
 *
 */
@Repository
public class PersonDaoImp implements PersonDao {
 
   @PersistenceContext
   private EntityManager em;
 
   @Override
   public void add(Person person) {
      em.persist(person);
   }
 
   @Override
   public List<Person> listPersons() {
      CriteriaQuery<Person> criteriaQuery = em.getCriteriaBuilder().createQuery(Person.class);
      @SuppressWarnings("unused")
      Root<Person> root = criteriaQuery.from(Person.class);
      return em.createQuery(criteriaQuery).getResultList();
   }
 
}
cs

@PersistenceContext주석은 주입하는 데 사용됩니다 EntityManagerDOA 클래스로 객체를.

 

 

Service class

 다음과 같이 패키지 @Service 아래에 클래스를  작성하십시오  com.boraji.tutorial.spring.service.

PersonService.java

1
2
3
4
5
6
7
8
9
10
package com.boraji.tutorial.spring.service;
 
import java.util.List;
 
import com.boraji.tutorial.spring.entity.Person;
 
public interface PersonService {
    void add(Person person);
    List<Person> listPersons();
}
cs

PersonServiceImp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.boraji.tutorial.spring.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.boraji.tutorial.spring.dao.PersonDao;
import com.boraji.tutorial.spring.entity.Person;
 
/**
 * @author imssbora
 *
 */
@Service
public class PersonServiceImp implements PersonService {
 
   @Autowired
   private PersonDao userDao;
 
   @Transactional
   @Override
   public void add(Person person) {
      userDao.add(person);
   }
 
   @Transactional(readOnly = true)
   @Override
   public List<Person> listPersons() {
      return userDao.listPersons();
   }
 
}
cs

 

persistence.xml 파일

폴더 persistence.xml아래  파일을 src/main/java/META-INF작성하고 다음 코드를 작성하십시오.

persistence.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">
 
  <persistence-unit name="LOCAL_PERSISTENCE">
    <description> Spring Hibernate JPA Configuration Example</description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
 
    <properties>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/BORAJI" />
      <property name="javax.persistence.jdbc.user" value="root" />
      <property name="javax.persistence.jdbc.password" value="admin" />
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
    </properties>
 
  </persistence-unit>
</persistence>
cs

이것은 persistence.xml를 구성하는 데 사용되는 EntityManager응용 프로그램 서버 또는 독립 실행 형 응용 프로그램 내에서. 데이터베이스 (연결 URL, 사용자 이름, 비밀번호 등) 및 ORM 관련 정보가 들어 있습니다.

Spring configuration

 패키지 @Configuration 아래에 클래스를  만듭니다  com.boraji.tutorial.spring.config.

@EnableTransactionManagement 트랜잭션 관리 기능을 사용하려면 주석으로이 구성 클래스에 주석을 답니다  .

AppConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.boraji.tutorial.spring.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
 
/**
 * @author imssbora
 *
 */
@Configuration
@EnableTransactionManagement
@ComponentScans(value = { @ComponentScan("com.boraji.tutorial.spring.dao"),
      @ComponentScan("com.boraji.tutorial.spring.service") })
public class AppConfig {
 
   @Bean
   public LocalEntityManagerFactoryBean geEntityManagerFactoryBean() {
      LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
      factoryBean.setPersistenceUnitName("LOCAL_PERSISTENCE");
      return factoryBean;
   }
 
   @Bean
   public JpaTransactionManager geJpaTransactionManager() {
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(geEntityManagerFactoryBean().getObject());
      return transactionManager;
   }
}
cs

Run application

위의 spring-hibernate-jpa 구성을 테스트 할 기본 클래스를 작성하십시오.

MainApp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.boraji.tutorial.spring;
 
import java.util.List;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import com.boraji.tutorial.spring.config.AppConfig;
import com.boraji.tutorial.spring.entity.Person;
import com.boraji.tutorial.spring.service.PersonService;
 
/**
 * @author imssbora
 *
 */
public class MainApp {
   public static void main(String[] args) {
      AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
 
      PersonService personService = context.getBean(PersonService.class);
 
      // Add Persons
      personService.add(new Person("Sunil""Bora""suni.bora@example.com"));
      personService.add(new Person("David""Miller""david.miller@example.com"));
      personService.add(new Person("Sameer""Singh""sameer.singh@example.com"));
      personService.add(new Person("Paul""Smith""paul.smith@example.com"));
 
      // Get Persons
      List<Person> persons = personService.listPersons();
      for (Person person : persons) {
         System.out.println("Id = "+person.getId());
         System.out.println("First Name = "+person.getFirstName());
         System.out.println("Last Name = "+person.getLastName());
         System.out.println("Email = "+person.getEmail());
         System.out.println();
      }
 
      context.close();
   }
}
cs

Output

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Hibernate: create table PERSONS (id bigint not null auto_increment, EMAIL varchar(255), FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (id)) engine=MyISAM
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: select person0_.id as id1_0_, person0_.EMAIL as EMAIL2_0_, person0_.FIRST_NAME as FIRST_NA3_0_, person0_.LAST_NAME as LAST_NAM4_0_ from PERSONS person0_
Id = 1
First Name = Sunil
Last Name = Bora
Email = suni.bora@example.com
 
Id = 2
First Name = David
Last Name = Miller
Email = david.miller@example.com
 
Id = 3
First Name = Sameer
Last Name = Singh
Email = sameer.singh@example.com
 
Id = 4
First Name = Paul
Last Name = Smith
Email = paul.smith@example.com
cs

 

Download Sources

spring-hibernate-jpa-example.zip18.19 KB

반응형

'JAVA/SPRING > SPRING' 카테고리의 다른 글

Spring Framework: annotation 정리  (0) 2017.12.04
Spring Web MVC, @Controller 어노테이션 정리  (0) 2017.12.04
반응형

관련 문서

목차


이 글은 스프링 2.x 기준으로 작성되었음.

사용빈도가 높은 어노테이션 위주로 정리.

목차에 없는 항목은 API 문서를 참고할 것. 구글링하는게속편한건함정

@Component

패키지: org.springframework.stereotype

버전: spring 2.5

설정 위치: 클래스 선언부 앞

<context:component-scan> 태그를 설정파일에 추가하면 해당 어노테이션이 적용된 클래스를 빈으로 등록하게 된다. 범위는 디폴트로 singleton이며 @Scope를 사용하여 지정할 수 있다.

사용하려면 XML 설정파일에 <context:component-scan>을 정의하고 적용할 기본  패키지를 base-package 속성으로 등록한다.

context:annotation-config 태그는 어노테이션과 관련해서 다음의 BeanPostProcessor를 함께 등록 한다.

  • @Required(RequiedAnnotationBeanPostProcessor)
  • @Autowired(AutowiredAnnotationBeanPostProcessor)
  • @Resource, @PostConstruct, @PreDestory(CommonAnnotationBeanPostProcessor)
  • @Configuration(ConfigurationClassPostProcessor)
  • 그 외 Repository, Service, Controller 포함

예를 들어 다음처럼 설정하면:

<context:component-scan base-package="xxx"/>

xxx 패키지 하위에 @Component로 선언된 클래스를 bean으로 자동 등록한다. bean의 이름은 해당 클래스명(첫글자는 소문자)이 사용된다.

<context:component-scan /> 요소에는 scoped-proxy 속성이 존재 한다. scoped-proxy는 <aop:scoped-poxy/>처럼 WebApplicationContext 에서만 유효하며 "session", "globalSession", "request" 이외의 scope는 무시 되며 아래의 3가지 값을 설정 할 수 있다.

  • no: proxy를 생성하지 않는다.(기본값)
  • interfaces: JDK Dynamic Proxy를 이용한 Proxy 생성
  • targetClass: 클래스에 대해 프록시를 생성(CGLIB를 이용한 Proxy 생성)
@Component
@Scope("prototype")   // 생략하면 싱글톤
public class Test {
       .....
}

CGLIB

기존의 자바 클래스파일로부터 자바의 소스코드를 동적으로 생성하는 라이브러리(자바 소스 변경)

http://sourceforge.net/projects/cglib/

스캔 대상 클래스 범위 지정하기

<context:include-filter> 태그와 <context:exclude-filter> 태그를 사용하면 자동 스캔 대상에 포함시킬 클래스와 포함시키지 않을 클래스를 구체적으로 명시할 수 있다.

<context:component-scan base-package="spring.demo" scoped-proxy="no">
   <context:include-filter type="regex" expression="*HibernateRepository"/>
   <context:exclude-filter type="aspectj" expression="..*IBatisRepository"/>
</context:component-scan>

위와 같이 <context:include-filter> 태그와 <context:exclude-filter> 태그는 각각 type 속성과 expresseion 속성을 갖는데, type 속성에 따라 expression 속성에 올 수 있는 값이 달라진다. type 속성에 입력가능한 값은 다음과 같다:

  • annotation: 클랙스에 지정한 어노테이션이 적용됐는지의 여부. expression 속성에서는 "org.example.SomeAnnotation"와 같은 어노테이션 이름을 입력한다.
  • assignable: 클래스가 지정한 타입으로 할당 가능한지의 여부.  expression 속성에는 "org.exampleSomeClass" 와 같은 타입 이름을 입력한다.
  • regex: 클래스 이름이 정규 표현식에 매칭되는 지의 여부.  expression 속성에는 "org\.example\.Default.*" 와 같이 정규표현식을 입력한다.
  • aspectj: 클래스 이름이 AspectJ 의 표현식에 매칭되는 지의 여부.  expression 속성에는 "org.example..*Service+" 와 같이 AspectJ 의 표현식을 입력한다.

@Required

패키지: org.springframework.beans.factory.annotation

버전: spring 2.0

설정 위치: setter 메서드 앞

Required 어노테이션은 필수 프로퍼티임을 명시하는 것으로 필수 프로퍼티를 설정하지 않을 경우 빈 생성시 예외를 발생시킨다.

import org.springframework.beans.factory.annotation.Required

public class TestBean {
    @Required
    private TestDao testDao;

    public void setTestDao(TestDao testDao) {
        this.testDao = testDao;
    }
}
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanpostProcessor"/>
<bean name="testBean"  class="han.test.TestBean">
    <property name="testDao" ref="testDao"/>
    <!-- @Required 어노테이션을 적용하였으므로 설정하지 않으면 예외를 발생시킨다. -->
</bean>

RequiredAnnotationBeanPostProcessor 클래스는 스프링 컨테이너에 등록된 bean 객체를 조사하여 @Required 어노테이션으로 설정되어 있는 프로퍼티의 값이 설정되어 있는지 검사한다.

사용하려면 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 하지만 이를 대신하여 <context:annotation-config> 태그를 사용해도 된다:

<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          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-3.1.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <context:annotation-config/>
</beans>

@Autowired

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: 생성자, 필드, 메서드(setter메서드가 아니여도 된다) 앞

의존관계를 자동설정할 때 사용하며 타입을 이용하여 의존하는 객체를 삽입해 준다. 그러므로 해당 타입의 빈객체가 존재하지 않거나 또는 2개 이상 존재할 경우 스프링은 예외를 발생시키게 된다.

options:

  • required: Autowired 어노테이션을 적용한 프로퍼티 중 반드시 설정할 필요가 없는 경우에 false값을 주어 프로퍼티가 존재하지 않더라도 스프링이 예외를 발생하지 않도록 한다. 기본값은 TRUE. ex) @Autowired(required=false)

사용하려면 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

@Autowired를 적용할 때 같은 타입의 빈이 2개 이상 존재하게 되면 예외가 발생하는데, Autowired도 이러한 문제가 발생한다. 이럴 때 @Qualifier를 사용하면 동일한 타입의 빈 중 특정 빈을 사용하도록 하여 문제를 해결할 수 있다.

@Autowired
@Qualifier("test")
private Test test;

@Qualifier

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: @Autowired 어노테이션과 함께 사용된다.

qualifier 어노테이션은 @Autowired의 목적에서 동일 타입의 빈객체가 존재시 특정빈을 삽입할 수 있게 설정한다. @Qualifier("mainBean")의 형태로 @Autowired와 같이 사용하며 해당 <bean>태그에 <qualifire value="mainBean" /> 태그를 선언해주어야 한다. 메서드에서 두개이상의 파라미터를 사용할 경우는 파라미터 앞에 선언해야한다.

options:

  • name: alias명

사용하려면 동일타입의 빈객체 설정에서 <qualifier value="[alias명]" />를 추가해 준다.

<bean id="user2" class="com.sp4.UserImpl">
    <property name="name" value="스프링"/>
    <property name="age" value="20"/>
    <property name="tel" value="000-0000-0000"/>
</bean>

<bean id="userService1" class="com.sp4.UserService"/>
public class UserService {
    @Autowired
    @Qualifier("user2")
    private User user;

    public String result() {
        return user.getData();
    }
}

@Resource

자바 6 및 JEE5에 추가된 것으로 어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용 한다. 스프링 2.5 부터 지원하는 어노테이션으로 스프링에서는 의존하는 빈 객체를 전달할 때 사용한다.

@Autowired와 흡사하지만 @Autowired는 타입으로(by type), @Resource는 이름으로(by name)으로 연결한다는 점이 다르다.

options:

  • name: 자동으로 연결될 빈객체의 이름을 입력한다. ex) @Resource(name="testDao")

사용하려면 <bean class="org.springframework.beans.factory.annotation.CommonAnnotationBeanPostProcessor"/> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

<beans>
    <!-- 기타 설정 생략 -->
    <context:annotation-config/>

    <bean id="user2" class="com.test.UserImpl" p:data="65536"/>
</beans>
public class UserService {
    @Resource(name="user2")
    private User user;
    //UserImpl user2 = new UserImpl();
    //User user = user2;

    public void setUser(User user) {
        this.user = user;
    }
    public String result() {
        return user.getData();
    }
}

@Scope

패키지: org.springframework.beans.factory.annotation

설정: prototype, singleton, request, session, globalSession

스프링은 기본적으로 빈의 범위를 "singleton" 으로 설정한다. "singleton" 이 아닌 다른범위를 지정하고 싶다면 @Scope 어노테이션을 이용하여 범위를 지정한다.

@Component
@Scope(value="prototype")
public class Worker {}
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class Worker {}

@PostConstruct

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 초기화 작업 수행 메서드 앞

의존하는 객체를 설정한 이후에 초기화 작업을 수행하기 위해 사용한다. 스프링에 의해 인스턴스가 생성된 후 어노테이션이 적용된 메서드가 호출된다. 사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@PostConstruct
public void init() {
    System.out.println("객체 생성 후 내가 먼저 실행된다.");
}

@PreDestroy

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 해당 작업 메서드 앞

컨테이너에서 객체를 제거하기 전에 해야할 작업을 수행하기 위해 사용한다.

사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@Inject

SR-330 표준 Annotation으로 Spring 3 부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다. @Inject를 사용하기 위해서는 클래스 패스 내에 JSR-330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 함에 유의해야 한다. 

@Service

@Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다. Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며 Service에 있는 @Autowired는 @Repository("xxxDao")에 등록된 xxDao와 변수명이 같아야 한다.

@Service("helloService")
public class HelloServiceImpl implements HelloService {
    @Autowired
    private HelloDao helloDao;

    public void hello() {
        System.out.println("HelloServiceImpl :: hello()");
        helloDao.selectHello();
    }
}

helloDao.selectHello(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다:

@Service("test2.testService")
//괄호 속 문자열은 식별자를 의미한다.
//괄호를 생략할 경우 클래스명 그대로 사용한다.
//따라서 ,같은 클래스명이 존재 할 시 같은 식별자가 생성되기때문에 에러가 발생한다.
public class TestService {
    public String result(int num1, int num2, String oper) {
        String str = null;

        if (oper.equals("+")) {
            //...
            return str;
        }
    }
}

@Resouce로 연결

@Resource(name="test2.testService")
//name에 필요한 것은 @Service("test2.testService") <- 여기서 괄호 속 문자열, 즉 식별자

private TestService service;
//TestService service = new TestService(); 라고 하는것과 같은 식

@RequestMapping(value="/test2/oper.action", method={RequestMethod.GET})
public String form() throws Exception {
    return "test2/write";
}

@Repository

패키지: org.springframework.stereotype

버전: spring 2.0

@Repository는 일반적으로 DAO에 사용되며 DB Exception을 DataAccessException으로 변환한다.

@Repository("bbs.boardDAO")
public class BoardDAO {
    private SqlSession sqlSession;

    public int insertBoard(Board dto) throws Exception {
        ...
    }
}
public class BoardServiceImpl implements BoardService {
    @Resource(name="bbs.boardDAO")
    private BoardDAO dao;

    public int insertBoard(Board dto){}
}

@Controller

http://noritersand.tistory.com/474

@RequestMapping

http://noritersand.tistory.com/475

@RequestParam

http://noritersand.tistory.com/357

@SessionAttributes

SessionAttribute annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용한다.

@Controller
@SessionAttributes("blog")
public class BlogController {
    // 중간생략

    @RequestMapping("/createBlog")
    public ModelMap createBlogHandler() {
        blog = new Blog();
        blog.setRegDate(new Date());
        return new ModelMap(blog);
    }

    // 중간생략
}

@SessionAttributes는 model로 할당된 객체 중 지정된 이름과 일치하는 객체를 세션 속성에도 추가한다.

@SessionAttributes("someSessionAttr")
class ExampleController2 {
	@RequestMapping("/test")
	public ModelAndView drawTest(ModelAndView view, @ModelAttribute("someSessionAttr") String someSessionAttr) {
		view.addObject("someSessionAttr", someSessionAttr);
		return view;
	}
}

@RequestBody

@RequestBody 어노테이션이 적용된 파라미터는 HTTP Request body의 내용이 전달된다.

참고: http://java.ihoney.pe.kr/283

@RequestMapping(value="/test")
public void penaltyInfoDtlUpdate(@RequestBody String body,
        HttpServletRequest req, HttpServletResponse res,
        Model model, HttpSession session) throws Exception  {

    System.out.println(body);
}

@ResponseBody

참고: http://ismydream.tistory.com/140

클라이언트에 JSON 형식의 값을 응답할 때 유용하다. 메서드에 @ResponseBody를 적용한 후 문자열을 리턴하면 그 값은 HTTP response header가 아니라 HTTP response body에 쓰여진다. 객체를 넘길경우 스프링에 내장된 JACKSON에 의해 문자열로 변환될 것이다.

또한 @ResponseBody가 적용된 컨트롤러는 context에 설정된 resolver를 무시한다.

@RequestMapping("/getVocTypeList")
@ResponseBody
public ArrayList<Object> getVocTypeList() throws Exception {
    HashMap<String, Object> vocData = gvocInf.searchVocTypeList();
    return (ArrayList<Object>) vocData.get("data");
}

@PathVariable

URL의 일부를 파라미터 혹은 변수로 사용한다.

package com.sp.ex;

@Controller("ex.exController")
public class ExController{
    @RequestMapping(value="/blog/{userId}/main.action", method=RequestMethod.GET)
    public String main(HttpServletRequest req
                       , @PathVariable String userId) throws Exception    {

        req.setAttribute("userId", userId);
        return "restful/result";
    }
}



출처 : http://noritersand.tistory.com/156


반응형
반응형

Spring Web MVC의 @Controller 클래스에서 클래스 레벨에 명시 가능한 어노테이션은 아래와 같다.


  • @ResponseBody: 모든 메써드의 리턴 오브젝트를 적절한 형태로 변환 후 HTTP 응답 메시지의 바디에 담아 반환한다. (오브젝트에서 바디로의 실제 변환은 HttpMessageConverter 인터페이스의 각 구현 클래스들이 수행한다. 예를 들면 String 리턴 타입은 StringHttpMessageConverter가 변환을 담당한다.) 클래스 레벨에 명시하면 View로의 반환을 완전히 배제하기 때문에 REST API 구현시 적합하다.


  • @RestController@Controller에 위에 설명한 @ResponseBody를 추가한 효과를 가진다. REST API 구현을 염두한 축약형 어노테이션이다.


  • @RequestMapping: 응답을 수행할 HTTP 요청을 명시할 수 있다.

    • path (StringString[]): 요청 URI를 명시한다. 배열을 통한 복수개의 요청 URI를 지정할 수 있다. 클래스 레벨에 명시한 값은 모든 메써드 레벨에 명시한 path 값 앞에 붙어 접두어 역할을 한다.
@RequestMapping("/v1/players")
  • @PropertySource: 프라퍼티 소스를 명시할 수 있다. 필드 레벨에서 @Value 등을 통해 클래스 레벨에서 명시한 프라퍼티 소스의 값을 주입할 수 있다.
// ROOT CLASSPATH(/src/main/java/resources)에 위치한 some.properties를 프라퍼티 소스로 명시한다.
@PropertySource("classpath:/some.properties")

클래스 필드 레벨

필드 레벨에 명시 가능한 어노테이션은 아래와 같다.


  • @Autowired: 적합한 이름의 스프링 빈을 자동으로 주입한다. 명백하게 1개의 스프링 빈만 존재할 경우 사용한다.


  • @Resource: 지정한 이름의 스프링 빈을 주입한다. 같은 타입의 스프링 빈이 2개 이상 존재할 경우 사용한다.

    • name (String): 주입할 스프링 빈의 이름이다.

  • @Value: 시스템 환경 변수, Java 환경 변수, Spring 환경 변수, 프라퍼티 리소스 상수 등의 값을 주입한다.


메써드 레벨

  • @RequestMapping: 메써드가 어떤 HTTP 요청을 처리할 것인가를 작성한다. 구체적인 작성 예는 아래와 같다.

@RequestMapping(
  /**
   * HTTP URI가 "/users"인 것만 처리한다. 만약 앞서 클래스 레벨에서 "/v1"이 명시되었다면 "/v1/users"를 처리하게 된다.
   */
  path = "/users",

  /**
   * HTTP 요청 메써드가 "POST"인 것만 처리한다.
   */
  method = RequestMethod.POST,

  /**
   * HTTP 요청 헤더가 "Content-Type: application/json;charset=UTF-8"인 것만 처리한다.
   * 다른 값이 들어올 경우 org.springframework.web.HttpMediaTypeNotSupportedException을 발생시킨다.
   * HTTP 요청 헤더에 명시된 Content-Type은 HTTP 요청 바디의 형식을 의미한다. 즉, 서버에서는 JSON 형식의 바디만 처리하겠다는 의미이다.
   * 참고로 GET 요청은 바디를 가지지 않으므로 아래 파라메터를 명시할 필요가 없다.
   */
  consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,

  /**
   * HTTP 응답 헤더로 "Content-Type: application/json;charset=UTF-8"을 반환한다.
   * 생략할 경우 메써드 리턴 타입에 따라 Content-Type을 자동으로 판단하여 반환한다.
   */
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)

메써드 아규먼트 레벨

  • 특정 어노테이션 없이 POJO 클래스를 아규먼트로 명시하면 HTTP 요청 메시지의 QueryString 문자열을 변환하여 저장한다.

  • @ValidJSR-303 (Bean Validation) 스펙에 명시된 어노테이션으로 요청 파라메터에 대한 유효성 검사가 가능하다. 유효성 검사 실패시 org.springframework.validation.BindException이 발생한다. 대상 아규먼트는 기본 타입 및 POJO 타입 모두 가능하다.

  • @RequestBodyHTTP 요청 메시지의 BODY를 변환하여 담을 아규먼트 앞에 명시한다. HTTP 스펙에 따라 GET 이외의 메써드에서만 명시 가능하다. (무시하고 명시할 경우 org.springframework.http.converter.HttpMessageNotReadableException이 발생한다.) 한편 앞서 설명한 @Valid를 추가로 명시할 수 있다. 유효성 검사 실패시 org.springframework.web.bind.MethodArgumentNotValidException을 발생시킨다.



출처: http://jsonobject.tistory.com/257 [지단로보트의 블로그]

반응형

+ Recent posts