Spring Framework의 특징

  • 경량의 컨테이너로써 자바 객체를 직접관리 (메모리 관리관련)
  • POJO(Plain Old Java Ojbect)  방식의 프레임워크
  • IoC(Inersion of Control) 지원
  • DI(Dependency Injection)지원
  • AOP(Aspect-Oriented Programming)지원
  • iBatis, myBatis, Hibernate 등의 데이터베이스 라이브러리를 지원한다.

특징

  • Java파일에서 Java 코드를 줄일 수 있다.
  • 반복되는 작업을 줄일 수 있어 기능 개발에 집중할 수 있다.
  • 프로젝트 관리가 용이하다.
  • 다수의 개발자와 동시에 프로젝트 하기가 용이하다.
  • 처음 프로젝트 셋팅이 다소 복잡하다.
  • 개념을 제대로 숙지하지 못하면 코드 분석 조차 하기 힘들다.

 스프링에서의 DI의 의미

- 부품들을 생성하고, 제품을 조립해주는 공정과정을 대신해 주는 라이브러리 (역할자)

 

 * 개발 핵심 처리 루틴의 수정 없이 제품(객체)를 다른 제품(객체)로 쉽게 대체하여 생성 가능하도록 하는 역할을 함.

 * 명세서에 따라서 자동적으로 부품을 활용하여 제품을 조립.

 * 생성하기 원하는 객체를 명세서(XML)에 기술하고, 그 부품과 의존성(Dependency)들을 보관하는 일을 처리. 그러한 데이터를 보관하는 공간을 컨테이너라 함. (IoC 컨테이너)

 

2-4) XML (Bean) Sample

 

* 빈(Bean) 객체는 반드시 클래스를 사용. 인터페이스나 추상클래스는 객체 생성이 불가능함.
* 빈 객체 생성, 객체 초기화, 객체 값(또는 레퍼런스) 주입.


id : 빈 객체 고유 이름 (접근 가능자)

name : 객체의 이름(별칭)

class : 생성할 클래스

constructor-arg : 초기값 설정 (생성자 함수 사용Java Class 에서

public Main(String name, String age){

      this.name = name;

      this.age = age;

}

property : 초기값 설정 (Setter함수 사용) Java Class 에서

public String name;   setter, getter 

<bean id=“빈 객체 고유 이름” name=“객체 이름” class=“생성할 클래스”>
    <property name=“초기값 설정” value=“프로퍼티 값”></property>
</bean>


짧게 생략 가능 DI setter 
<property name=“초기값 설정” value=“프로퍼티 값”></property>

<property name="height">
	<value>프로퍼티 값</value>
</property>


DI 생성자
<bean id="빈 객체 고유 이름" class="생성할 클래스">
		<constructor-arg value="생성자 첫번째" />
		<constructor-arg value="생성자 두번째" />
		<constructor-arg>  // 3번째 생성자 ArrayList<String> 해당하는
			<list>
				<value생성자List[0]</value>
				<value>생성자List[1]</value>
			</list>
		</constructor-arg>
        
 줄여서 생략시 (c: constructor 줄임, p: property 줄임)      
<bean id="빈 객체 고유 이름" class="생성할 클래스" 
			c:papaName="생성자첫번째" c:mamiName="생성자두번째" p:sisterName="프로퍼티 값">
		<property name="초기값 설정" value="프로퍼티 값" />
	</bean>

 

Java Bean 선언된 걸 xml에 선언된 Bean과 합치는 방법

package com.javalec.ex;

import java.util.ArrayList;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfig {

	@Bean
	public Student student1(){
		
		ArrayList<String> hobbys = new ArrayList<String>();
		hobbys.add("수영");
		hobbys.add("요리");
		
		Student student = new Student("홍길동", 20, hobbys);
		student.setHeight(180);
		student.setWeight(80);
		
		return student;
	}
	
}
<?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 http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	
	<context:annotation-config />
	<bean class="com.javalec.ex.ApplicationConfig" />
	
	<bean id="student2" class="com.javalec.ex.Student">
		<constructor-arg value="홍길순"></constructor-arg>
		<constructor-arg value="30"></constructor-arg>
		<constructor-arg >
			<list>
				<value>마라톤</value>
				<value>요리</value>
			</list>
		</constructor-arg>
		<property name="height" value="190" />
		<property name="weight" value="70" />
	</bean>

</beans>
package com.javalec.ex;

import java.util.ArrayList;

public class Student {

	private String name;
	private int age;
	private ArrayList<String> hobbys;
	private double height;
	private double weight;
	
	public Student(String name, int age, ArrayList<String> hobbys) {
		this.name = name;
		this.age = age;
		this.hobbys = hobbys;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	public void setHobbys(ArrayList<String> hobbys) {
		this.hobbys = hobbys;
	}
	
	public void setHeight(double height) {
		this.height = height;
	}
	
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public ArrayList<String> getHobbys() {
		return hobbys;
	}
	
	public double getHeight() {
		return height;
	}
	
	public double getWeight() {
		return weight;
	}
	
}
package com.javalec.ex;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

		public static void main(String[] args) {
			
			AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
			Student student1 = ctx.getBean("student1", Student.class);
			System.out.println("이름 : " + student1.getName());
			System.out.println("나이 : " + student1.getAge());
			System.out.println("취미 : " + student1.getHobbys());
			System.out.println("키 : " + student1.getHeight());
			System.out.println("몸무게 : " + student1.getWeight());
			
			Student student2 = ctx.getBean("student2", Student.class);
			System.out.println("이름 : " + student2.getName());
			System.out.println("나이 : " + student2.getAge());
			System.out.println("취미 : " + student2.getHobbys());
			System.out.println("키 : " + student2.getHeight());
			System.out.println("몸무게 : " + student2.getWeight());
			
			ctx.close();
		}
	
}

xml Bean 선언된 걸 Java에 선언된 Bean과 합치는 방법

<?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="student2" class="com.javalec.ex.Student">
		<constructor-arg value="홍길순"></constructor-arg>
		<constructor-arg value="30"></constructor-arg>
		<constructor-arg >
			<list>
				<value>마라톤</value>
				<value>요리</value>
			</list>
		</constructor-arg>
		<property name="height" value="190" />
		<property name="weight" value="70" />
	</bean>

</beans>
package com.javalec.ex;

import java.util.ArrayList;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource("classpath:applicationCTX.xml")
public class ApplicationConfig {

	@Bean
	public Student student1(){
		
		ArrayList<String> hobbys = new ArrayList<String>();
		hobbys.add("수영");
		hobbys.add("요리");
		
		Student student = new Student("홍길동", 20, hobbys);
		student.setHeight(180);
		student.setWeight(80);
		
		return student;
	}
	
}
package com.javalec.ex;

import java.util.ArrayList;

public class Student {

	private String name;
	private int age;
	private ArrayList<String> hobbys;
	private double height;
	private double weight;
	
	public Student(String name, int age, ArrayList<String> hobbys) {
		this.name = name;
		this.age = age;
		this.hobbys = hobbys;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	public void setHobbys(ArrayList<String> hobbys) {
		this.hobbys = hobbys;
	}
	
	public void setHeight(double height) {
		this.height = height;
	}
	
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public ArrayList<String> getHobbys() {
		return hobbys;
	}
	
	public double getHeight() {
		return height;
	}
	
	public double getWeight() {
		return weight;
	}
	
}
package com.javalec.ex;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

		public static void main(String[] args) {
			
			AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
			
			Student student1 = ctx.getBean("student1", Student.class);
			System.out.println("이름 : " + student1.getName());
			System.out.println("나이 : " + student1.getAge());
			System.out.println("취미 : " + student1.getHobbys());
			System.out.println("키 : " + student1.getHeight());
			System.out.println("몸무게 : " + student1.getWeight());
			
			Student student2 = ctx.getBean("student2", Student.class);
			System.out.println("이름 : " + student2.getName());
			System.out.println("나이 : " + student2.getAge());
			System.out.println("취미 : " + student2.getHobbys());
			System.out.println("키 : " + student2.getHeight());
			System.out.println("몸무게 : " + student2.getWeight());
			
			ctx.close();
			
		}
	
}

스프링 빈 생명주기

인터페이스 이용시

어노테이션 이용시

스프링 빈 범위(scope)

scope default 는 singleton이다.


properties 외부파일 사용

오라클 경우

context.xml 파일설정

<context:property-placeholder location="classpath:config/properties/db.properties"/>


   <!--  bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.DriverManagerDataSource"-->
   <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${db.driverClassName}"/>
      <property name="url" value="${db.url}" />
      <property name="username" value="${db.username}" />
      <property name="password" value="${db.password}" />
   </bean>
db.properties 설정

db.driverClassName=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@오라클주소이름 ex)localhost:1521:aaa or www.xxxx.xxx:1521:aaa
db.username=아이디 (오라클 아이디)
db.password=패스워드 (오라클 비밀번호)

MySql 경우

context.xml 파일설정

<context:property-placeholder location="classpath:config/properties/db.properties"/>


   <!--  bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.DriverManagerDataSource"-->
   <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${db.driverClassName}"/>
      <property name="url" value="${db.url}" />
      <property name="username" value="${db.username}" />
      <property name="password" value="${db.password}" />
   </bean>
db.properties 설정

db.driverClassName=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/aaa?
      useUnicode=true&amp;characterEncoding=utf8&amp;verifyServerCertificate=false&amp;useSSL=false&amp;serverTimezone=UTC
db.username=아이디 (mysql 아이디)
db.password=패스워드 (mysql 비밀번호)

2. 능동 변환 : SpEL

두 번째는 SpEL(Spring Expression Language)를 이용하는 방법이다.

빈 팩토리 후처리기에서 치환을 해주는 수동적인 방법과 달리, 빈 오브젝트에 직접 접근할 수 있는 표현식을 이용해 원하는 프로퍼티 값을 능동적으로 가져오는 방법이다. (스프링 3.0 에서 소개됨)

SpEL은 다른 빈의 프로퍼티에 접근, 메소드 호출, 다양한 연산도 지원하며 클래스 정보에도 접근할 수 있다. (생성자를 호출해서 오브젝트를 만들 수도 있음)

 

<util:properties> 태그를 이용하면 프로퍼티 파일을 읽어서 Properties 타입의 빈으로 만들 수 있다.

<util:properties id="database" location="classpath:database.properties"/>

<context:property-placeholder> 처럼 빈 팩토리 후처리기로 동작해서 빈의 값을 변경하는 것이 아니라, 단순히 프로퍼티 파일의 내용을 담은 Properties 타입의 빈을 만들어 준다.

이렇게 database.properties의 내용을 빈으로 만들어두고, dataSource 빈에서는 SpEL을 이용해서 database 빈 오브젝트에서 원하는 정보를 읽어오게 한다. (SpEL에서는 Map의 get() 메소드를 호출해주는 표현식이 존재하는데, []안에 키 값을 넣어주면 된다.)

<bean id="dataSource" class="..DataSource">

    <!-- database 빈 오브젝트에서 db.driverclass를 키로 갖는 값을 가져오라는 표현식 -->

    <property name="driverClass" value="#{database['db.driverclass']}"/>     

    ...

</bean>

@Value("#{database['db.driverClass']}") 로도 가능하다.

 


AOP

<bean id="logAop" class="com.javalec.ex.LogAop" />
	
	<aop:config>
	
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut id="publicM" expression="within(com.javalec.ex.*)"  />
			<aop:around pointcut-ref="publicM" method="loggerAop" />
		</aop:aspect>
		
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut id="publicM" expression="within(com.javalec.ex.*)"  />
			<aop:before pointcut-ref="publicM" method="beforeAdvice" />
		</aop:aspect>
		
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut id="publicM" expression="within(com.javalec.ex.*)"  />
			<aop:after-returning pointcut-ref="publicM" method="afterReturningAdvice" />
		</aop:aspect>
		
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut id="publicM" expression="within(com.javalec.ex.*)"  />
			<aop:after-throwing pointcut-ref="publicM" method="afterThrowingAdvice" />
		</aop:aspect>
		
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut id="publicM" expression="within(com.javalec.ex.*)"  />
			<aop:after pointcut-ref="publicM" method="afterAdvice" />
		</aop:aspect>
		
	</aop:config>

 

'Spring' 카테고리의 다른 글

인터셉터 HandlerInterceptorAdapter 제공 메소드  (0) 2020.12.18
이클립스 Spring STS 수동설치  (0) 2020.12.15

+ Recent posts