Use of @Configurable annotation.

Not, all types(beans) used in a Spring Based Application are Spring managed. Sometimes, we need to inject some dependency into some Types which are not Spring Managed. The most common example being, injection of Service or DAO layer within the Entity class. Now the instances of Entity classes are being created using the new operator, i.e. they are not Spring Managed. Now we want to inject the corresponding Service or DAO Type which is Spring Managed within these Entity Types, and these can be performed with the help of @Configurable. It is the Aspects, which performs all the underlying engineering and ,makes this thing possible. Let's see an example.


@Configurable
public class Person {

 @Autowired
 ResourceBundleThemeSource themeSource;
 
 private String firstName;
 private String lastName;
 private int age;
 private Address address;
 @CustomDateFormat
 Date birthDate;
 MultipartFile profile;
 
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Address getAddress() {
  return address;
 }
 public void setAddress(Address address) {
  this.address = address;
 }
 public Date getBirthDate() {
  return birthDate;
 }
 public void setBirthDate(Date birthDate) {
  this.birthDate = birthDate;
 }
 public MultipartFile getProfile() {
  return profile;
 }
 public void setProfile(MultipartFile profile) {
  this.profile = profile;
 }
 
 @Override
 public String toString() {
  return "Person [ThemeSource=" + themeSource.getTheme("default")
    + ", firstName=" + firstName + ", lastName=" + lastName
    + ", age=" + age + ", address=" + address + ", birthDate="
    + birthDate + ", profile=" + profile + "]";
 }
 
 
}


Here, Person can be considered as a Model or Entity class, and it has got a bean of type ResourceBundleThemeSource injected into it. This bean is Spring Managed and the Person class is annotated with @Configurable. I have defined the themeSource in a java based configuration, instead of XML based as:
@Configuration
@Import(........
@EnableSpringConfigured
public abstract class SpringWebApplicationConfig extends WebMvcConfigurerAdapter {
@Autowired
 Environment environment;

 @Value(.......
 
 
 @Bean
    public ResourceBundleThemeSource themeSource()
    {
     ResourceBundleThemeSource resourceBundleThemeSource = new ResourceBundleThemeSource();
     resourceBundleThemeSource.setBasenamePrefix("theme-");
     return resourceBundleThemeSource;
    }

}

One of the most important things to be noticed out here, is that the class is annotated with @EnableSpringConfigured. The following dependencies should be included in the pom.xml along with the plugin definitions.
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aspects</artifactId>
   <version>4.1.6.RELEASE</version>
  </dependency>

  <dependency>
   <groupId>javax.persistence</groupId>
   <artifactId>persistence-api</artifactId>
   <version>1.0.2</version>
  </dependency>

  <dependency>
   <groupId>javax.cache</groupId>
   <artifactId>cache-api</artifactId>
   <version>1.0.0</version>
  </dependency>

  <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>aspectj-maven-plugin</artifactId>
   <version>1.6</version>
   <configuration>
    <complianceLevel>1.6</complianceLevel>
    <source>1.6</source>
    <target>1.6</target>
    <outxml>true</outxml>
    <verbose>true</verbose>
    <showWeaveInfo>true</showWeaveInfo>
    <aspectLibraries>
     <aspectLibrary>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
     </aspectLibrary>
    </aspectLibraries>
   </configuration>
   <executions>
    <execution>
     <phase>process-classes</phase>
     <goals>
      <goal>compile</goal>
     </goals>
    </execution>
   </executions>
  </plugin>
  

Now after maven build, the target model class Person, would get the required dependencies, weaved in it, by AspectJ. So, every time we create an object of Person class which necessarily is not Spring-Managed will have the declared dependency weaved in it. We can verify it just by logging the object toString() versione as I have done in one of my Controller method just like the following.

@RequestMapping(value="Emp.......
public ModelAndView getEmployeeProfileLayout()
 {
  ...............
  Person person = new Person();
  person.setLastName("PAUL");
  log.debug(" The Person is:"+person);
 
  ............
  ...................
 }

We can now find that the person object would contain an instance of type ResourceBundleThemeSource even though the object has been created using new operator.

Really awesome isn't!!!! Please note, from command line I am explicitly invoking the goal aspectj:compile to perform the compile time weaving.

Comments

Popular posts from this blog

Spring WS - Part 4

Spring WS - Part 5