Tag Archives: SpringFramework

Spring 5.0에서 바뀌는 점 + Java9에서 바뀌는 점

Java9 대응

따라서, Java9에서의 변화가 Spring5 에서의 변화겠지

JDK7에선 붜가 변했는지 잘 모르고 넘어갔고 <>??
JDK8에선 stream, lambda(람바다?람드아?)가 나왔는데 크게 사용률이 높지 않았다
JDK9에서는 좀 많은 변화가 있는 것 같다

‘ http://blog.takipi.com/5-features-in-java-9-that-will-change-how-you-develop-software-and-2-that-wont/

추가되는 기능

  • repl – jshell (커맨드라인 명령 지원 )
    • 다른 언어에서 지원되는거 보고 부러워하던 기능 아닌가 ㅎ
  • Microbenchmarks(JMH)
    • 벤치마크 기술이라고 하는데…
  • GC 개선
    • G1엔진을 쓴다고 하는데.. 빨라진다고?
  • http2.0
    • 2.0 스펙도 봐야한다.
  • OS컨트롤 능력 강화
    • 예를 들자면 PID 가져오는 기능이라던가

사라지는 기능

그런게 있었나 싶은 기능들 : Json API, Money currency

 

Spring5 추가기능

Mono 되는거 뭐 추가되는 것 같았는데…

DispatcherHandler라는 클래스 중심으로 flow가 추가되는 것 같고…

아직 제대로 안봐서 모르겠다.

 

Spring5 지원중지

Portlet, JDO, JSF 등 공부할 생각도 못했던 몇몇 기술들 지원중단
Hibernate3, 등 구버전 중단.
좀 더 과감해졌으면 좋겠지만…

최근에 Spring재단이 거의 Jaav 표준을 주도하고 있는 것 같아서
조심스러운가보다.

https://spring.io/blog/2015/06/10/feedback-welcome-spring-5-system-requirements

어설프게 몇 줄 읽어봤는데 역시나 댓글에 반발이 조금 있는 것 같다.

Portlet3.0(JSR362)스펙은 2017.Jan에 새로 발표된 것 같은데.. 지원 중단이군 ㅎ
공부할거 하나 줄었다.
왜 필요한가 의문이 좀 있었다. servlet 페이지에 삽입되어서 사용자의 상태를 기억하기도 하고 페이지 일부분의 동적인 변경을 담당하는 기술.. 정도로만 알고 있었는데
오늘 갑자기 protlet 관련 검색하다가 springframework 5.0소스에 portlet 패키지가 없는걸 보고 알게됏다.
DispatcherPortlet
https://en.wikipedia.org/wiki/Java_Portlet_Specification
http://stackoverflow.com/questions/1480528/what-is-the-difference-between-a-portlet-and-a-servlet
몇가지 찾아보니 portlet 기술은 jsp 페이지에 jstl방식으로 fragment를 삽입하는 기술의 일종인 것 같은데
최근에 ajax widget이나 template engine등이 이를 완전히 대체하고 있어서… 굳이 필요한가 싶은 생각이 든다.
그런의도에서 portlet 지원을 중단한게 아닌가….? 싶다.

spring properties 코드에 injection하기

컨트롤러 코드

@Controller
public class HomeController {
	
private static final Logger LOG = LoggerFactory.getLogger(HomeController.class);
	
	//@Value("${username}")
	//private String username;
	
	@Value("#{aPropertiesFactoryBean.prop1}")
	private String prop1;
	
	@Value("#{aPropertiesFactoryBean.username}")
	private String username;
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		LOG.info("Welcome home! the client locale is "+ locale.toString());
		System.out.println(username);
		System.out.println(prop1);
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}

설정코드

<?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:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<bean id="aPropertiesFactoryBean"
		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="singleton" value="true" />
		<property name="ignoreResourceNotFound" value="true" />
		<!-- <property name="properties">
			<props>
				<prop key="prop1">http://192.168.0.2/</prop>
				<prop key="prop2">value2</prop>
			</props>
		</property> -->
		<!-- Allow foo.conf to override default properties -->
		<property name="location" value="classpath:/META-INF/spring/beansugar.properties" />
	</bean>

	<context:property-placeholder
		location="classpath:/META-INF/spring/beansugar.properties" />
</beans>

properties파일

##FileName : beansugar.properties
username=usertest
url=http://192.168.0.51/

 

 

SpringSecurity 에서 사용자 정보 (받아오기)뽑아서 쓰기

스프링 시큐리티를 사용하다가 사용자 정보를 뽑아서 써야되는데 참 갑갑할때가 있다.

내가 만든 것도 아니라서 어디서 뽑아다가 써야될지도 잘 모르겠고

스프링 시큐리티 너무 복잡해서 어떻게 찾을지도 잘 모르겠고 그럴때가 많다.

google search keyword : spring security get current user details

http://stackoverflow.com/questions/248562/when-using-spring-security-what-is-the-proper-way-to-obtain-current-username-i

스택오버플로우가 글이 날라가지는 않을 것 같지만 혹시나 해서 그냥 퍼놔야겠다.

1. SpringSecurityContextHolder를 사용하는 방법

public static User getCurrentUser() {

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal()

    if (principal instanceof MyUserDetails) return ((MyUserDetails) principal).getUser();

    // principal object is either null or represents anonymous user -
    // neither of which our domain User object can represent - so return null
    return null;
}

2. 뭔지 잘 모르겠는데 좋아보이는 방법 – 토큰을 집어오는것같다.

@Controller
public class KnoteController {
  @RequestMapping(method = RequestMethod.GET)
  public java.lang.String list(Model uiModel, UsernamePasswordAuthenticationToken authToken) {
    if (authToken instanceof UsernamePasswordAuthenticationToken) {
      user = (User) authToken.getPrincipal();
    }
    ...
}

3. User는 아니지만 UserPrincipal을 가져오는 방법

  private String principal;
  @Principal
  public setPrincipal(String principal){
    this.principal=principal;
  }

 

 

SpringData, JPA, Hibernate 적용하기

그냥 프로젝트를 사용하는 경우에는 아주 쉽게 적용이 가능하다.

템플릿에 있는대로 설정하면 된다.

hibernate.cfg.xml을 classpath;~ 경로에 놓고 셋팅해준다.

—-설정방법은 검색, 또는 이클립스 기능을 따라가면서 완성 —-

 

MVC의 경우에는 스프링에서 관리하는 빈 형태를 유지해줘야하는데 이 때문에 설정이 더욱 복잡해진다.

임의로 Bean형태를 삽입하고튜토리얼에 있는 생성코드를 삽입해주면 간단하다.

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();


Persistence.createEntityManagerFactory(arg0)

윗쪽은 SessionFactory생성코드 아랫쪽은 entityManagerFactory생성코드… bean에 이 코드를 대충 쑤셔넣고 임의로 생성된 그 bean을 받아서 사용할 수도 있을 것 같다.
스프링에 연결하는 코드도 대략 그 형태일 것이라 짐작된다.

개발자라면…. 이런 조잡한 방법보다 조금 더 깔끔한 방법을 원한다.

위 방법을 사용하면 dao 코드도 만들어서 콜백을 쑤셔넣고 해야되는 귀찮음이 있다.

 

SpringFramework + SpringData(JPA프레임워크) + Hibernate

이렇게 하면 귀찮은 dao코드를 제거한 채로 코딩이 가능하다고 한다.

 

 

 

but was actually of type [$Proxy17]

뭔 거지같은 에러메세지가 났다.

@transactional을 지우니까 해결됐다.
이유는 파악을 못 했다.

일단 오류발생 가능성으로 의심되는 부분들 모두 기록해놓는다.

1. service가 꼭 인터페이스일 필요가 있는가라는 생각에 클래스로 만들었다. 그리고 이 클래스를 인터페이스 사용할때와 같은 방법으로 사용했다.
2. 이 클래스에서 Transactional을 사용했다.

외국사이트 검색결과

http://stackoverflow.com/questions/8391944/getting-spring-error-bean-named-x-must-be-of-type-y-but-was-actually-of-ty

지도 잘 모르겠는데 Guess해봤다고 한다.
바이트코드가 무거워서 그렇다고한다.
이걸 붙이라는데 잘 안됐다.

다시 Transactional을 붙이니 같은 오류가 발생한다.

아직 해결을 못했다.

인터페이스로 바꿔서 써보면 해결이 될까? 시간이 없으니 다음으로 미룬다.

결국 해결…
org.aspectj.util.PartialOrder$PartialComparable

몇가지 수정하다가 이런걸 발견했다.
디펜던시 문제였던것같다
메이븐의 고질병
알아서 좀 해주면 안되나
lib에 때려넣는것보다 에러가 더 많이나면 어쩌라는건지
aspectj weaver라이브러리 넣어주면된다.