Open topgaren opened 4 years ago
Installation : $ brew install redis
Running server : $ redis-server
Connecting client : $ redis-cli
Maven dependency (pom.xml)
<!-- Spring Data Redis -->
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.7.RELEASE</version>
</dependency>
<!-- Jedis -->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Configuration with Java
package com.linestudio.practice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfiguration {
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName("127.0.0.1");
jedisConnectionFactory.setPort(6379);
return jedisConnectionFactory;
}
@Bean
public StringRedisTemplate stringRedisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(jedisConnectionFactory());
return stringRedisTemplate;
}
}
Add Component Scan(root-context.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 https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="com.linestudio.practice.config" />
</beans>
Test code
package com.linestudio.practice;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class RedisTests {
@Inject
private JedisConnectionFactory jedisConnectionFactory;
@Inject
private StringRedisTemplate stringRedisTemplate;
@Test
public void RedisConnectionTest() throws Exception {
try {
RedisConnection connection = jedisConnectionFactory.getConnection();
System.out.println(connection);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void RedisTemplateTest() throws Exception {
System.out.println(stringRedisTemplate.opsForValue().get("greeting"));
}
}
Maven dependency
<!-- MySQL 라이브러리 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!-- MyBatis 라이브러리 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- MyBatis-Spring 라이브러리 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- Spring JDBC -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
Configuration with 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"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- DataSource Default Config -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/[DATABASE_NAME]?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Seoul" />
<property name="username" value=[USER_NAME] />
<property name="password" value=[PASSWORD] />
</bean>
<!-- SqlSessionFactory Config -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- <property name="mapperLocations" value="classpath:[PACKAGE PATH]/mapper/**/*Mapper.xml" /> -->
</bean>
<!-- SqlSession Config -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<mybatis-spring:scan base-package="[PACKAGE PATH].mapper"/>
</beans>
Mapper XML Example
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="[MAPPER PACKAGE PATH]">
<select id="[METHOD NAME]" resultType="[VO PACKAGE PATH]">
<![CDATA[
SELECT *
FROM tbl_board
WHERE bno > 0;
]]>
</select>
<insert id="insert">
INSERT INTO tbl_board(title, content, writer)
VALUES (#{title}, #{content}, #{writer});
</insert>
<insert id="insertSelectKey" useGeneratedKeys="true" keyProperty="bno">
INSERT INTO tbl_board(title, content, writer)
VALUES (#{title}, #{content}, #{writer});
</insert>
<select id="read" resultType="com.linestudio.practice.board.domain.BoardVO">
SELECT *
FROM tbl_board
WHERE bno = #{bno};
</select>
<delete id="delete">
DELETE
FROM tbl_board
WHERE bno = #{bno};
</delete>
<update id="update">
UPDATE tbl_board
SET title = #{title},
content = #{content},
writer = #{writer},
update_date = NOW()
WHERE bno = #{bno};
</update>
</mapper>
Download Lombok : https://projectlombok.org/download (Version : 1.18.4 at 2019. 8. 5)
Installing
$ java -jar ~/Download/lombok.jar
~/Applications/SpringToolSuite4/Contents/Eclipse/SpringToolSuite4.ini
Maven dependency
<!-- Lombok -->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
Maven pom.xml
<org.aspectj-version>1.8.0</org.aspectj-version>
<!-- AspectJ (This is default setting) -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
AOP가 적용될 대상
/* com.linestudio.practice.concert.Performance.java */
package com.linestudio.practice.concert;
public interface Performance {
public void perform();
}
/* com.linestudio.practice.concert.PerformanceImpl.java */
package com.linestudio.practice.concert;
import org.springframework.stereotype.Component;
import lombok.extern.log4j.Log4j;
@Log4j
@Component
public class PerformanceImpl implements Performance {
@Override
public void perform() {
log.info("~~~!!!@@~~~!!~@~#~@~~@@@!!");
}
}
Advice 작성
/* com.linestudio.practice.concert.Audience.java */
package com.linestudio.practice.concert;
import org.aspectj.lang.ProceedingJoinPoint;
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;
import lombok.extern.log4j.Log4j;
@Aspect
@Component
@Log4j
public class Audience {
@Pointcut("execution(* com.linestudio.practice.concert.Performance*.perform(..))")
public void performance() {}
// @Before( "performance()" )
// public void silenceCellPhones() {
//
// log.info("Silencing cell phones");
// }
//
// @Before( "performance()" )
// public void takeSeats() {
//
// log.info("Taking seats");
// }
//
// @AfterReturning("execution(* com.linestudio.practice.concert.Performance*.perform(..))")
// public void applause() {
//
// log.info("CLAP! CLAP! CLAP!");
// }
//
// @AfterThrowing("execution(* com.linestudio.practice.concert.Performance*.perform(..))")
// public void demandRefund() {
//
// log.info("Demanding a refund");
// }
@Around( "performance()" )
public void watchPerformance(ProceedingJoinPoint jp) {
try {
log.info("Silencing cell phones");
log.info("Taking seats");
jp.proceed();
log.info("CLAP! CLAP! CLAP!");
} catch(Throwable e) {
log.info("Demanding a refund");
}
}
}
root-context.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="com.linestudio.practice.concert" />
<aop:aspectj-autoproxy />
</beans>
주의 : servlet-context.xml에서 aop 적용 패키지 보다 상위의 패키지를 component-scan 하는 경우 autoproxy 설정이 덮어 씌워지므로 프록시가 적용되지 않는 문제가 발생할 수 있다.
Test code
package com.linestudio.practice;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.zerock.concert.Performance;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
@Log4j
public class PerformanceTests {
@Setter(onMethod_ = @Autowired)
private Performance performance;
@Test
public void testClass() {
assertNotNull(performance);
log.info(performance);
log.info(performance.getClass().getName());
}
@Test
public void testPerform() {
performance.perform();
}
}
Reference Spring in Action, Craig Walls, Tech Trans group T4 역, Manning, 제 4판, 2015 코드로 배우는 스프링 웹 프로젝트, 구멍가게 코딩단, 남가람북스, 개정판, 2018
Maven dependencies
<!-- Spring security web -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- Spring security config -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- Spring security core -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- Spring security taglibs -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
security-context.xml 생성 (path : /WEB-INF/spring/security-context)
<?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:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Spring security filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
</param-value>
</context-param>
Maven dependencies
<!-- Quartz -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.0</version>
</dependency>
<!-- Quartz jobs -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.0</version>
</dependency>
root-context.xml 설정
<task:annotation-driven>
을 추가
<?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"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<task:annotation-driven/>
Example Code
package com.linestudio.practice.works.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.extern.log4j.Log4j;
@Component
@Log4j
public class FileCheckTask {
@Scheduled(cron="0 * * * * *")
public void checkFiles() throws Exception {
log.warn("File Check Task run...............");
log.warn("==============================================================");
}
}
크론(cron) 표현식 : 필드
필드 | 값의 허용 범위 | 허용된 특수문자 |
---|---|---|
초(Seconds) | 0~59 | , - * / |
분(Minutes) | 0~59 | , - * / |
시(Hours) | 0~23 | , - * / |
일(Day) | 1~31 | , - * ? / L W |
월(Month) | 1~12 or JAN ~ DEC | , - * / |
요일(Week) | 1~7 or SUN ~ SAT | , - * ? / L # |
연도(Year) | empty or 1970 ~ 2009 | , - * / |
*
: 모든 값을 뜻함.?
: 특정한 값이 없음을 뜻함.-
: 범위를 뜻함. Example) "월요일에서 수요일까지"는 MON-WED
로 표현..
: 특별한 값일 때만 동작. Example) "월, 수, 금"은 MON, WED, FRI
으로 표현./
: 시작시간 / 단위. Example) "0분부터 매 5분마다"는 0/5
로 표현.L
: 일(Day)에서 사용하면 마지막 일, 요일(Week)에서 사용하면 마지막 요일(=토요일).W
: 가장 가까운 평일. Example) 15W
는 15일에서 가장 가까운 평일을 의미.#
: 몇 번째주의 무슨 요일을 표현. Example) 3#2
는 2번째 주 수요일을 의미.Reference 코드로 배우는 스프링 웹 프로젝트, 구멍가게 코딩단, 남가람북스, 개정판, 2018 Wikipedia - "cron" https://zamezzz.tistory.com/197
Spring MVC Project Configuration
(Spring version : 5.1.0.RELEASE / Java version : 11 / IDE : SpringToolSuite 4)
Common Configuration
New Project > Other > Spring Legacy Project > Spring MVC Project
Maven pom.xml
<org.springframework-version>5.1.0.RELEASE</org.springframework-version>
<java-version>11</java-version>
<source>11</source>
<target>11</target>
Context Path(or Context Root) Configuration
<Context docBase=[PROJECT_NAME] path=[PATH] … />