Spring beginner questions about annotations and thread safety - spring

I am not sure if I am allowed to ask more than one question in a post, but here it is,
For example I have the following,
Controllers
#Controller
public class FooController{
#Autowired
private FooService fooService;
#RequestMapping(value="/foo", method=RequestMethod.POST)
public #ResponseBody foo(#RequestBody FooRequest request){
}
}
#Controller
public class BarController{
#Autowired
private FooService fooService;
#RequestMapping(value="/bar", method=RequestMethod.POST)
public #ResponseBody bar(#RequestBody FooRequest request){
}
}
Service
public class FooService{
private Foo foo;
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
public String doFoo(String str){
return foo.doFoo(str);
}
}
class to do the job
public class Foo{
public String doFoo(String str){
return (str + " is foo");
}
}
create beans using dependency injection
<context:annotation-config/>
<bean id="fooService" class="com.myapp.service.FooService">
<property name="foo" ref="foo"></property>
</bean>
<bean id="foo" class="com.myapp.foo.Foo">
</bean>
My questions are:
I did not use #service annotation at class FooService, should I use it, and why?
Is this configuration thread-safe or not, and why (how is it achieved if it is thread-safe)?
Where can I find a tutorial about the layers (dao layers, service layer ...) used in Spring design and the purpose of such a design?

You don't have to use annotations if you declare your beans in xml-config, as you did.
It is. Each bean, although a singleton, is stateless. So no concurrent modifications can occur.
For example in wikipedia. It's not spring-specific. Look for articles about three-tier architecture

Using it would simply avoid the need for declaring the bean using XML. You chose to use annotations for your other beans. I would thus also use annotations for this one.
Yes, it is, because Spring makes sure everything is properly wired up and initialized, with a synchronization barrier, before serving any request
This is a very broad question. Layering is useful for separation of concerns, testability, ability to demarcate transactions declaratively, etc.

#Repository, #Service, or #Controller (sub-annotations of #Components) are used to mark specific classes, so they can be considered more-or-less as metadata. However, there are some features of the Spring framework that can take advantage of these. One of them is automatic component scanning (a given java package will be searched for classes with the above annotations and these classes can be used as Spring beans, as if they were declared in XML). To enable this, you should put this into your spring context:
<context:component-scan base-package="my.service.package"/>
More on this can be found here: http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-classpath-scanning
Another use-case is for AOP. You can create annotation-aware pointcuts by which you can select say all your repository classes.
The Spring beans in context are brought up one by one, so there is no chance of concurrency kicking in. However, there can be circular dependencies between beans and Spring may or may not resolve this properly.
For both DAO and service stuff, the current Spring 3 documentation provides many examples and probably the best source for learning: http://static.springsource.org/spring/docs/3.0.x/reference/index.html If you'd like to have an all-round knowledge I'd recommend trying out JdbcTemplate, Rowmappers and an ORM based configuration with Hibernate.

Related

Wiring multiple beans with the same dependency via Spring Boot #Configuration

In older Spring MVC apps, where you'd specify application.xml and declare your app's beans so that Spring DI could instantiate them and wire them together, you might have something like this:
<bean id="chargeFactory" class="com.example.myapp.ChargeFactory" />
<bean id="paymentService" class="com.example.myapp.DefaultPaymentService">
<ref id="chargeFactory"/>
</bean>
<bean id="chargeAuditor" class="com.example.myapp.ChargeAuditor">
<ref id="chargeFactory"/>
</bean>
Which might help wire up the following code:
public interface PaymentService {
public void makePayment(Payment payment);
}
public class DefaultPaymentService implements PaymentService {
#Autowired
private ChargeFactory chargeFactory;
#Override
public void makePayment(Payment payment, String key) {
Charge charge = chargeFactory.createCharge(key);
charge.doCharge(payment);
}
}
public class ChargeAuditor {
#Autowired
private ChargeFactory chargeFactory;
public void auditAllCharges(String key) {
List<Charge> charges = chargeFactory.getAllCharges(key);
// blah whatever
}
}
How do you accomplish the same bean wiring in Spring Boot with the #Configuration class? For example:
#Configuration
public class MyAppInjector {
#Bean
public ChargeFactory chargeFactory() {
return new ChargeFactory();
}
#Bean
public PaymentService paymentService() {
return new DefaultPaymentService(chargeFactory());
}
#Bean
public ChargeAuditor chargeAuditor() {
return new ChargeAuditor(chargeFactory());
}
}
This might work but introduces some issues:
It would force me to have to write value constructors for all my classes, which goes against everything I see in literally every tutorial/article I've come across. Plus, if I had to do that, then there's no real value to #Autowired anyways...
At this point I'm essentially doing "DIY DI", which is OK, except I'm trying to deliberately use Spring DI :-)
Every time I call chargeFactory() I'm getting a new (prototype-style) ChargeFactory instance. Maybe I want a singleton. Using this approach I have to hand-roll my own singleton implementation.
Sure, I can do all of this, but I feel like I'm flagrantly misusing/misunderstanding how #Configuration is supposed to be used, because it seems like I'm introducing a whole lot of DIY/homegrown code to solve something Spring DI should be able to do for me.
How would I reference the chargeFactory bean and wire it into both the "provider methods" for the paymentService and chargeAuditor beans? Again, looking for the Java-based #Configuration solution instead of writing an XML document to define the wirings.
I found this article which seems to be the only tutorial/documentation (surprisingly) on wiring Spring Boot apps via #Configuration (which leads me to believe there might be other/better methods...), but it does not address:
How to specify singleton vs prototype bean instantiation patterns
If multiple instances of a bean-class exist, how do I specify which instance gets wired into which dependency?
How do I get around not defining value constructors for all my classes, and just let Spring/#Autowired inject fields automagically?
When you call chargeFactory() , spring won't create new instance everytime. Give it a try and see. Same object will be returned. Anyways
You can do something like this.
#Bean
public PaymentService paymentService(ChargeFactory chargeFactory) { return new DefaultPaymentService(chargeFactory); }

aspectj check broken layer access in spring boot

I try to use aspectj for checking whether the layers of the architecture are broken, e.g. the access from controller to repository without using a service between
Now this is marking every method call to a autowired annotated within de.fhb.controller.
but how can i then limit that to Repositories for example?
The package structure looks like this:
de.fhb.controller
de.fhb.service
de.fhb.entity and and so on.
my aspect looks like this
#Aspect
public class Layer {
#DeclareError("within(de.fhb.controller..*) && #annotation(org.springframework.beans.factory.annotation.Autowired) " )
private static final String typeWarning = "You try to access through many layers";
}
the repository:
#Repository
public interface BoxRepository extends JpaRepository<Box, Long>{
public List findByPrio(long prio);
}
and the controller that should be checked by aspects:
#RequestMapping("/box")
#Controller
public class BoxController {
#Autowired
private BoxRepository boxRepository; // negative example
#Autowired
private BoxService boxService;
#RequestMapping(value = "/")
public String list(Model model) {
List boxes = boxRepository.findAll(); // negativ example
model.addAttribute("boxes", boxes);
return "box/list";
}
for further look: repository at github
Your pointcut
within(de.fhb.controller..*) &&
execution(de.fhb.repository.BoxRepository *(..))
means in prose: Intercept any method in package de.fhb.controller or its sub-packages which has a return type of de.fhb.repository.BoxRepository, but in your code is no such method. So you will never see a compiler error.
;-)
Updated answer after question update:
You need to intercept calls to methods of types with a #Repository annotation:
within(de.fhb.controller..*) &&
call(* (#org.springframework.stereotype.Repository *).*(..))
But in order to do that you need to switch from Spring AOP to full-blown AspectJ with compile-time weaving, i.e. you need to use the AspectJ compiler Ajc to compile and weave your aspect. The reason is that Spring AOP does not support the call() pointcut, but this is what you need. An execution() pointcut will not help you here, but that is the only one supported by a proxy-based "AOP lite" framework like Spring AOP. You just need to weave this one aspect with AspectJ, the other aspects can still use Spring AOP. But then need to take care about AspectJ not picking up your other aspects.

Spring AOP: advice is not triggered

Trying to design simple aspect,that will print word "logg" to console,when any of public methods executed.
aspect:
#Aspect
public class LoggingAspect {
#Pointcut("execution(public * *(..))")
public void publicServices() {
};
#Before("publicServices()")
public void logg() {
System.out.println("logg");
}
}
xml config:
<context:component-scan base-package="aspectlogging" />
<aop:aspectj-autoproxy/>
<bean id="loggingAspectHolder" class="aspectlogging.LoggingAspect"/>
simple bean:
package aspectlogging;
#Component
public class TestableBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
test:
public class TestLogging {
public static void main(String[] args) {
TestableBean tb = new TestableBean();
tb.setName("yes");
tb.getName();
}
}
I expect,that result of running of TestLogging will be "logg" word in console,and no output returned.
Do I understand AOP correctly in this case?
With #Around advice, you need to have a ProceedingJoinPoint pjp argument to the advising method and to call pjp.proceed() at the point in the advisor when you want the wrapped method to be called. It's easier to use #Before advice really, when what you've done will otherwise work just fine.
[EDIT]: Also, you must let Spring construct your beans for you instead of directly calling new. This is because the bean object is actually a proxy for your real object (which sits inside it). Because your target object doesn't implement an interface, you will need to have the cglib library on your classpath in addition to the Spring libraries. (Alternatively, you can go with using AspectJ fully, but that requires using a different compiler configuration.)
To create your beans, you first need to create a Spring context and then query that for the bean instance. This means you change from:
TestableBean tb = new TestableBean();
To (assuming you're using Spring 3, and that your XML config is in "config.xml" somewhere on your classpath):
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
TestableBean tb = context.getBean(TestableBean.class);
The rest of your code remains the same (after adjusting for import statements and possibly additional dependencies).
Not quite sure on this one, but maybe you need to use a spring managed TestableBean to have spring AOP pick up the method call.
edit: of course, you can't use #Around the way that you provided - but this subject has been addressed by another answer, so it's omitted here.
edit2: If you need help on how to get a spring managed bean, please feel free to ask. but since you already got your aspect bean set up, I believe you can handle this :)
edit3: Hehe. Ok.. maybe not :)
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
will load your application context.
Load beans from there by calling:
TestableBean testableBean = (TestableBean )ctx.getBean("testableBean ");
Define the TestableBean just like you did with your Aspect bean.
edit4: Now I'm pretty sure that the fault is the non-spring managed bean.
Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as there is no requirement to introduce the AspectJ compiler / weaver into your development and build processes. If you only need to advise the execution of operations on Spring beans, then Spring AOP is the right choice. If you need to advise domain objects, or any other object not managed by the Spring container, then you will need to use AspectJ.
Taken from: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html

How to overwrite Spring service beans by name, using annotations only

Given I have a Spring bean configured as
#Service("myService")
public class DefaultService extends MyService {
}
and a class using this bean
public class Consumer {
#Autowired
#Qualifier("myService")
private MyService service;
...
}
I now want my project, that includes the preceding classes, to have Consumer another implementation of MyService being injected. Therefore I would like to overwrite the bean myService
#Service("myService")
public class SpecializedService implements MyService {
}
resulting in Consumer carrying now an instance of SpecializedService instead of DefaultService. By definition I cannot have two beans with the same name in the Spring container. How can I tell spring, that the definition of the new service shall overwrite the older one? I don't want to modify the Consumer class.
Either define the service bean explicitly
<bean id="myService" class="x.y.z.SpecializedService" />
or component-scan it.
In either event, in your application context, avoid explicitly defining DefaultService and avoid component-scanning it.
Exclude it from component-scan by using a filter
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
Not sure if there is a way to do it with only annotations (other than removing the #Service annotation from DefaultService).
Annotation based wiring happens before the XML based configuration, that means beans defined in XML will
overwrite those wiring done by Annotations.
So defining it explicitely in XML, like Willie has said will do the work
<bean id="myService" class="x.y.z.SpecializedService" />
Spring recommends using XML for service and repository beans and annotation for MVC beans. It also recommends #Autowired without component scanning. But Annotation are in general encouraged, although it merges code and configuration together (against seperation of concerns).
Second thing is to use #Qualifiers("id of declared bean") where it is being passed.
I know , its late . Still posting it.
You should have different names for different implementations of MyService.
For instance
#Service("mySpecializedService")
public class SpecializedService implements MyService {
}
#Service("myService")
public class DefaultService extends MyService {
}
While autowiring them ( say in Controller) , you may use #Qualifier to inject desired implementation as mentioned below.
To get default implementation
#Autowired
#Qualifier("myService")
MyService myService;
To get specialized implementation
#Autowired
#Qualifier("mySpecializedService")
MyService myService;

Use Spring #Transactional in Scala

We have a mixed Java and Scala project, which uses Spring transaction management. We are using the Spring aspects to weave the files with #Transactional annotated methods.
The problem is, that the Scala classes aren't woven with the Spring transaction aspects. How can I configure Spring to regard the transaction in Scala?
Spring needs your transaction boundary to begin with Spring-managed beans, so this precludes #Transactional Scala classes.
It sounds like the simple solution is to make service facades which are #Transactional Java classes instantiated as Spring beans. These can delegate to your Scala service/core code.
A Scala-only solution is to use Eberhard Wolff's closure that creates a manual transaction. Usage:
transactional() {
// do stuff in transaction
}
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionManagement.scala
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionAttributeWithRollbackRules.scala
Found here: http://www.slideshare.net/ewolff/scala-and-spring (slide 41)
License: Apache
There is nothing special about Spring's #Transactional support in Scala and you can use it without any Java code. Just make sure that you have "pure" traits for beans, which implementations would use #Transactional annotation. You should also declare a bean with PlatformTransactionManager type (if you are using .xml-based Spring configuration, you should use "transactionManager" for bean name, see EnableTransactionManagement's JavaDoc for details). Also, if you are using annotation-based configuration classes, be sure that these classes are placed in their own dedicated files, i.e. don't place any other classes (companion object is OK) in the same file. Here is simple working example:
SomeService.scala:
trait SomeService {
def someMethod()
}
// it is safe to place impl in the same file, but still avoid doing it
class SomeServiceImpl extends SomeService {
#Transactional
def someMethod() {
// method body will be executed in transactional context
}
}
AppConfiguration.scala:
#Configuration
#EnableTransactionManagement
class AppConfiguration {
#Bean
def transactionManager(): PlatformTransactionManager = {
// bean with PlatformTransactionManager type is required
}
#Bean
def someService(): SomeService = {
// someService bean will be proxied with transaction support
new SomeServiceImpl
}
}
// companion object is OK here
object AppConfiguration {
// maybe some helper methods
}
// but DO NOT place any other trait/class/object in this file, otherwise Spring will behave incorrectly!

Resources