Combine 2 Spring boot application - java

Just following Spring Guides http://spring.io/guides#gs I took gs-rest-service and gs-accessing-data-jpa. Now I want to combine them in one application, and that is where like more understanding of new org.springframework.boot.SpringApplication is needed.
In gs-rest-service config looks emazing, that is almost absent
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
gs-accessing-data-jpa is more like Spring XML JavaConfig based app.
#Configuration
#EnableJpaRepositories
public class CopyOfApplication {
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(H2).build();
}
// 2 other beans...
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(CopyOfApplication.class);
CustomerRepository repository = context.getBean(CustomerRepository.class);
//...
}
}
How to combine them?
Does it mean that I need to re-write SpringApplication.run now on more detailed level ?

In the Spring Boot application simply add the dependencies from the JPA sample (the ones which you don't already have.
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M7")
compile("org.springframework:spring-orm:4.0.0.RC1")
compile("org.springframework.data:spring-data-jpa:1.4.1.RELEASE")
compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
compile("com.h2database:h2:1.3.172")
testCompile("junit:junit:4.11")
}
or instead of this you could also use the spring boot starter project for Spring Data JPA. In that case the dependencies would look like the following.
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M7")
compile("org.springframework.boot:spring-boot-starter-data-jpa:0.5.0.M7")
compile("com.h2database:h2:1.3.172")
testCompile("junit:junit:4.11")
}
This will pull in all needed dependencies.
Next copy the CustomerRepository to the Spring Boot application. That basically should be everything you need. Spring Boot auto-configure now detects Spring Data JPA and JPA and will bootstrap hibernate, spring data for you.
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
ApplicationContext context= SpringApplication.run(Application.class, args);
CustomerRepository repository = context.getBean(CustomerRepository.class);
//...
}
}

Related

Spring AOP adviced methods do not work. My configuration seems ok

I'm trying to create a demo AOP application but it just does not work right.
I read through all tutorials and got it working with #RestController but as I tried it with a plain java spring driven application I just can't get it to work. Please review my files and tell me where my mistake lies in.
Application Class
#SpringBootApplication
#ComponentScan("com.xetra.experimental")
#EnableAspectJAutoProxy
public class AoptryoutnowebApplication {
public static void main(String[] args) {
SpringApplication.run(AoptryoutnowebApplication.class, args);
DefaultClassToAspectImpl defaultClassToAspectImpl = new DefaultClassToAspectImpl();
defaultClassToAspectImpl.doStuff();
}
}
ClassToAspect Interface
public interface ClassToAspect {
void doStuff();
}
ClassToAspect Implementation
#Component
public class DefaultClassToAspectImpl implements ClassToAspect {
#FooAnnotation
public void doStuff(){
System.out.println("DoStuff!");
}
}
Annotation for Pointcut
public #interface FooAnnotation {
}
Aspect Class
#Aspect
public class FooAspect {
#Pointcut("#annotation(FooAnnotation)")
public void methods(){
}
#Before("methods()")
public void doAspect(){
System.out.println("FooAspect before");
}
}
Try this:
replace #EnableAspectJAutoProxy with #EnableAspectJAutoProxy(proxyTargetClass = false)
change pointcut to
#Pointcut("execution (* your.package..*.*(..)) && #annotation(fooAnnotation))")
The problem is you are using a non Spring managed instance by doing new DefaultClassToAspectImpl(). Spring AOP only works for Spring managed beans, because by default Spring AOP is proxy based.
So instead of doing new DefaultClassToAspectImpl() you should be obtaining the instance from the ApplicationContext. When using Spring Boot the SpringApplication.run call returns an ApplicationContext. Here you can use one of the getBean methods to obtain the instance you want.
ApplicationContext ctx = SpringApplication.run(AoptryoutnowebApplication.class, args);
ClassToAspect bean = getBean(ClassToAspect.class);
bean.doStuff();
This way you get the Spring managed

Custom MongoDB spring data repository

I want to implement custom repo with Spring data mongodb.
Application.java:
#SpringBootApplication
public class Application implements CommandLineRunner{
#Autowired
private CustomerRepositoryCustom repo;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println(this.repo.customMethod());
}
}
My custom repository CustomerRepositoryCustom.java
public interface CustomerRepositoryCustom {
List<Customer> customMethod();
}
Custom implementation CustomCustomerRepositoryImpl.java
public class CustomCustomerRepositoryImpl implements CustomerRepositoryCustom {
#Autowired
private MongoTemplate mongoTemplate;
#Override
public List<Customer> customMethod() {
return this.mongoTemplate.findAll(Customer.class);
}
}
Code Structure
-Application.java
dal
model...
repository
-CustomCustomerRepositoryImpl.java
-CustomerRepositoryCustom.java
When I try to build it, i get an error:
**Description**:
Field repo in socketApp.Application required a bean of type 'socketApp.dal.repository.CustomerRepositoryCustom' that could not be found.
**Action**:
Consider defining a bean of type 'socketApp.dal.repository.CustomerRepositoryCustom' in your configuration.
You have to make Spring aware of your repository. For a Spring Boot application this is typically done by adding this annotation to your application ...
#EnableMongoRepositories("com.package.path.to.repository")
.... thereby telling Spring Boot where to look for Mongo repositories and then let your interface extend org.springframework.data.mongodb.repository.MongoRepository.
For example:
public interface CustomerRepositoryCustom extends MongoRepository {
List<Customer> customMethod();
}
Alternatively, you could annotate your CustomCustomerRepositoryImpl with #Repository and ensure that it is in a package which is scanned by Spring Boot.

Spring MVC unit test. Spring Boot Application eads wrong configuration

I have some problem with configuration my unit test. I have mock-test class configuration:
#TestConfiguration
public class TestContext {
#Bean
// #Qualifier("userTestServiceImplWithMongoDB")
public UserService userService() {
return Mockito.mock(UserService.class, "userServiceImplWithMongoDB");
}
#Bean
// #Qualifier("taskTestServiceImplWithMongoDB")
public TaskService taskService() {
return Mockito.mock(TaskService.class, "taskServiceImplWithMongoDB");
}
}
This file is in src/test/java directory. I start my application with class:
#SpringBootApplication
#Configuration
#EnableMongoRepositories
#ComponentScan
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
My problem is that application starts with wrong configuration - this one from my test config class.
I use MongoDB repositories and I have service layer using thats repositories.
I followed this instructions: Some tutorial.
I am new to Spring, do you know what I can do to fox it?
Have a nice day :)
The tutorial you are following is not for spring, not spring-boot. It is still a good tutorial to use MockMvc, however it does not cover how to load the context through spring-boot.
Check this to setup a unit test with Spring-Boot: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class YourTest {
...
}

Spring Boot: Is it safe to pass many Instances for CommandLineRunner

I'm a bit new to Spring Boot. I have an Application.java class where I have some code:
#SpringBootApplication(exclude = JpaRepositoriesAutoConfiguration.class)
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
...
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner App(DBReportRepository dbReportRepository,
ClientRepository clientRepository, FileParser fileParser,
MessagingService messagingService, ClientReportFactoryImpl clientReportFactory) ...
I was wondering is it a good practice to pass so many parameters (which are #Services annotated classes) to CommandLineRunner.
Or am I making Spring Boot do too much and there is another way to make Spring Boot be aware of those #Services classes.
Turned out my spring boot configuration was missing an AppConfig class. Without it I could only use #Autowired with #Component classes or #Service classes which were passed as arguments to CommandLineRunner. I created the AppConfig.java looking like this:
#Configuration
#ComponentScan(basePackages = "your.main.package")
public class AppConfig {
}
And after that I could use the #Autowired everywhere possible.

How to create a REST service with spring-boot?

I'm using spring-boot and want to integrate a simple REST service as follows.
#Controller
#RequestMapping("/content")
public class MyServiceRest extends SpringBeanAutowiringSupport {
#RequestMapping(method = RequestMethod.GET)
public String test() {
return "OK";
}
}
Result: both localhost:8080/<app-name>/services/content results "No service was found.". Why?
Do I have to explicit publish the service somehow?
Maybe it is due to my dispatcher servlet?
#Bean
public ServletRegistrationBean dispatcherServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(new CXFServlet(), "/services/*");
registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
return registration;
}
Since you are using Spring Boot, make sure that your application is correctly setup by adding the correct annotations. For instance,
#EnableAutoConfiguration
#EnableWebMvc
#Configuration
#ComponentScan
/*
* Application Setups using Spring boot.
*/
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#EnableWebMvc is the annotation to add for using Spring MVC with Spring boot.
And then you can define your controller as you did in your question.
add package with controller class to #Component scan in main class like: #ComponentScan( basePackages = { "your.package.with.controller" } ), this happens when spring didn't initialize (doesn't know about) controller
you should also add url mapping for your method
#RequestMapping(method = RequestMethod.GET, value = "url_here",
try
#RequestMapping(method = RequestMethod.POST, value = "/",
In the latest version of Spring Boot, that I am currently using, the web Service would address be http://localhost:8080/content
Also, the class I use to launch the service looks as follows:
#ComponentScan("eu.buzea")
#EnableAutoConfiguration
#EnableTransactionManagement
#SpringBootApplication
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Source Code
https://drive.google.com/open?id=0BzBKpZ4nzNzUWmJmOTFwbTFjWWM
using Swagger
http://localhost:7070/swagger-ui.html#/
**Cheers*
As of current spring-boot.1.5.6 there is no requirement using cxf.
Just use a #RestController with #GetMapping, and be happy to access localhost:8080/content.

Categories

Resources