How do I autowire a field when running Spring4JUnitRunner test? - spring

I'm using Spring 3.1.0.RELEASE. I'm having trouble autowiring a private variable from a Spring4JUnitRunner class. My JUnit class is ...
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "file:src/main/webapp/WEB-INF/dispatcher-servlet.xml" })
public class RegistrationControllerTest {
#Autowired
private ApplicationContext applicationContext;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private HandlerAdapter handlerAdapter;
private RegistrationController controller;
#Before
public void setUp() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
// I could get the controller from the context here
controller = new RegistrationController();
final RegistrationValidation registrationValidation = new RegistrationValidation();
controller.setRegistrationValidation(registrationValidation);
}
Not sure if its relevant, but here's my dispathcer-servlet.xml file ...
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<context:component-scan base-package="com.myco.eventmaven" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/messages" />
</bean>
</beans>
Here is my controller. The "usersDao" field is null during my test, causing NullPointerExceptions (works fine when I run it as a normal webapp in JBoss) ...
#Controller
#RequestMapping("/registrationform.jsp")
public class RegistrationController {
private static Logger LOG = Logger.getLogger(RegistrationController.class);
#Autowired
private RegistrationValidation registrationValidation;
#Autowired
private UsersDao usersDao;
public void setRegistrationValidation(
RegistrationValidation registrationValidation) {
this.registrationValidation = registrationValidation;
}
// Display the form on the get request
#RequestMapping(method = RequestMethod.GET)
public String showRegistration(Map model) {
LOG.debug("called GET method.");
final Registration registration = new Registration();
model.put("registration", registration);
return "user/registrationform";
}
// Process the form.
#RequestMapping(method = RequestMethod.POST)
public String processRegistration(Registration registration, BindingResult result) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String nextPage = "user/registrationform";
// set custom Validation by user
registrationValidation.validate(registration, result);
if (result.hasErrors()) {
return nextPage;
} else {
// Save the user to the database.
if (usersDao.saveUser(registration)) {
nextPage = "user/registrationsuccess";
} // if
} // if
return nextPage;
}
The class of the member field, usersDao, is annotated with the #Component annotation ...
#Component("usersDao")
public class UsersDaoImpl implements UsersDao {
What additional configuration do I need to add to properly autowire the dao object in my JUnit class? Thanks, -

You're getting the null because you're instantiating RegistrationController yourself, instead of getting the bean from Spring. You almost figured that out for yourself:
// I could get the controller from the context here
controller = new RegistrationController();
You could, and you should. Remove those two lines, and use the following on the field declartion:
#Autowired
private RegistrationController controller;

Related

Spring not roll back transaction if exception throws in the application

I developed the application using spring transactions and insert records in the table.
I'm explicitly throwing the exception in DAO class but spring is inserting the record into the table rather than roll back the transaction.
I have created the two applications as below . In Case 1 record is inserted into table even though exception is thrown . But In Case 2 no record is inserted and spring roll back the transaction successfully. Can you explain me the difference between these two applications.
Case 1:
Item.java
public class Item {
int itemNo;
String itemName;
String itemType;
String itemSize;
public int getItemNo() {
return itemNo;
}
public void setItemNo(int itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemType() {
return itemType;
}
public void setItemType(String itemType) {
this.itemType = itemType;
}
public String getItemSize() {
return itemSize;
}
public void setItemSize(String itemSize) {
this.itemSize = itemSize;
}
}
ItemDao
#Service
public class ItemDao {
#Autowired
JdbcTemplate jdbcTemplate ;
void insert(Item item){
jdbcTemplate.update("insert into item_test(itemno, itemtype,itemsize,itemname) values (?,?,?,?)", new Object[]{item.getItemNo(),item.getItemType(),item.getItemSize(),item.getItemName()});
int a=2/0;
}
}
ItemService.java
#Service
public class ItemService {
#Autowired
ItemDao itemDao;
#Transactional
public void insert(Item item){
try{
itemDao.insert(item);
}
catch(Exception e){
e.printStackTrace();
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ct = new ClassPathXmlApplicationContext("spring.xml");
ItemService itemService = ct.getBean("itemService", ItemService.class);
Item item = new Item();
item.setItemNo(1234);
item.setItemName("sofa");
item.setItemSize("4");
item.setItemType("furniture");
itemService.insert(item);
}
}
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
<context:component-scan base-package="com.spring.springtransaction" />
<!-- Creating TransactionManager Bean, since JDBC we are creating of type
DataSourceTransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- MySQL DB DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#locahost:1521:xe)))" />
<property name="username" value="system" />
<property name="password" value="system" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="itemService" class="com.spring.springtransaction.ItemService" />
</beans>
Case 2:
ItemService.java
#Service
public class ItemService {
#Autowired
ItemDao itemDao;
#Autowired
ItemManger itemManger;
#Transactional
public void insert(Item item){
try{
itemManger.insert(item);
}
catch(Exception e){
e.printStackTrace();
}
}
}
ItemManger.java
#Service
public class ItemManger {
#Autowired
ItemDao itemDao;
#Transactional
public void insert(Item item){
itemDao.insert(item);
}
}
ItemDao.java
#Service
public class ItemDao {
#Autowired
JdbcTemplate jdbcTemplate ;
void insert(Item item){
jdbcTemplate.update("insert into item_test(itemno, itemtype,itemsize,itemname) values (?,?,?,?)", new Object[]{item.getItemNo(),item.getItemType(),item.getItemSize(),item.getItemName()});
int a=2/0;
}
}
Annotate you ItemDao as #Repository instead of #Service
You should execute unit test with spring Transactional context instead of main , for example using TestNG:
#ContextConfiguration(classes = {ConfigurationClass.class})
#ActiveProfiles({"test"})
public class TestItemDAO extends AbstractTransactionalTestNGSpringContextTests {
#Autowired
private ItemDao dao;
#Test
public void testItemDao() {
dao.insert(item);
}
}
Remove the try block, you are trying to handle the exception so this is reason why RollbackException is not cutting the transaction stream.

#Autowired Spring service is null in Play Framework 2.6 application

I'm refactoring an application from Play Framework 2.2.x to Play Framework 2.6.x, and in the updated version of the app an #Autowired spring service is null (I didn't use "new" so that Spring would be confused).
AuthentecatedAction class:
#Scope("prototype")
#Component
public class AuthenticatedAction extends Action<Authenticated>
{
private final Logger log = LoggerFactory.getLogger(getClass());
#Autowired
ABCUserService ABCUserService;
#Autowired
AccessTokenService accessTokenService;
#Autowired
AccessTokenValidator accessTokenValidator;
#Override
public CompletionStage<Result> call(Http.Context ctx)
{
AccessToken accessToken;
try {
accessToken = accessTokenService.getAccessTokenFromHeader(ctx._requestHeader().headers());
} catch (Throwable throwable) {
return ResultUtils.handleError(new ValidationException(FORBIDDEN, String.format("Access token service is null. %s", throwable.getMessage())));
}
// Some more code here
}
// Some more code here
}
Here accessTokenService is #Autowired, but it is always null.
AccessTokenService class:
#Service
public class AccessTokenService extends JedisBaseService
{
private final Logger log = LoggerFactory.getLogger(getClass());
#Autowired
private ConfigurationService configurationService;
#Autowired
private EncryptionService encryptionService;
#Inject
public AccessTokenService(JedisPool jedisPool) {
super(jedisPool);
}
// some methods
}
JedisBaseService class:
public class JedisBaseService extends Controller
{
private final Logger log = LoggerFactory.getLogger(getClass());
private JedisPool jedisPool;
#Inject
public JedisBaseService(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
// some methods
// TODO: Check that solution with iserting JedisPool works
// See https://github.com/playframework/play-plugins/tree/master/redis for reference
protected Jedis getJedis()
{
return jedisPool.getResource();
}
}
Please, help me understand why #Autowired in AuthentecatedAction class accessTokenService is always null.
EDIT:
I should probably add, that my build.sbt file contains the line:
// https://mvnrepository.com/artifact/org.springframework/spring-context
"org.springframework" % "spring-context" % "4.3.10.RELEASE"
My routes file contains following lines:
POST /accesstokens #api.controller.accesstoken.AccessTokenController.createAccessToken()
DELETE /accesstokens #api.controller.accesstoken.AccessTokenController.deleteAccessToken()
So, I use dynamic controller dispatching to manage controller instances (by prefixing a controller class name with the # symbol in the routes file).
There is a controller for access tokens:
#Controller
public class AccessTokenController extends ABCController
{
#Autowired
private AccessTokenService accessTokenService;
#Autowired
private ABCUserService ABCUserService;
#Autowired
private ActivityCreationService activityCreationService;
#Autowired
private LiveUpdateService liveUpdateService;
#BodyParser.Of(BodyParser.TolerantJson.class)
#ResponseContentType(type = "accessToken")
public Result createAccessToken() throws ABCControllerException
{
// Implementation
}
public Result deleteAccessToken() throws ABCControllerException
{
// Implementation
}
}
Global object of my application that delegates controller instances management:
public class ABCGlobal
{
private final Logger log = LoggerFactory.getLogger(getClass());
protected static ApplicationContext ctx;
private final ActorSystem system;
#Inject
public ABCGlobal(ActorSystem system) {
this.system = system;
}
public static ApplicationContext getApplicationContext()
{
return ctx;
}
public void onStart(Application app)
{
String springConfigurationName = app.configuration().getString("spring.context");
ctx = new ClassPathXmlApplicationContext(springConfigurationName);
log.info("Loading spring configuration: {}", springConfigurationName);
// Some other code
}
// see: http://typesafe.com/blog/announcing-play-framework-21-the-high-velocit
public <A> A getControllerInstance(Class<A> clazz)
{
return ctx.getBean(clazz);
}
// Some other code
}
Here is the associated conf/components.xml file that is used to configure Spring:
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="api, service"/>
<context:property-placeholder location="classpath:application-base.conf" />
<context:property-placeholder location="classpath:application.conf" />
<bean class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean" id="resourceConverterFactory">
<property name="serviceLocatorInterface" value="service.resource.conversion.ResourceConverterFactory">
</property>
</bean>
<bean class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean" id="scraperFactory">
<property name="serviceLocatorInterface" value="service.scraping.ScraperFactory">
</property>
</bean>
<bean id="storageService" class="service.storage.impl.MongoGridFSStorageService"/>
<bean id="configurationService" class="service.configuration.impl.PlayConfigurationService">
<constructor-arg value="com.typesafe.config.Config" name="config">
</constructor-arg>
</bean>
<bean id="mailService" class="service.mail.impl.MailGunApiMailService"/>
</beans>
And in my application-base.conf file I have the following:
# Spring configuration
# ~~~~~
# Define what spring context should be used.
spring.context="components.xml"

Spring dependency config problems

Hello guys,
I am new to Spring and currently I am working on a web project in which I use Spring MVC and Spring dependency injection. I have three classes. UserService, HomeController and User. In HomeController I invoke UserService's fetchUser method which returns me a new Instance of the User class. It is a simple logic I use to reproduce my real project problem. I am not using any database in this simple project. When I invoke the fetchUserMethod I am getting a NullPointerException. I am using Glassfish 4.0. Could you please help me ?
Thank you !
Here is my web.xml
`<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 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/aplicationContext.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>`
Here is my applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="userService" class="services.UserService"/>
<bean id="homeController" class="controllers.HomeController">
<property name="userService" ref="userService"/>
</bean>
</beans>
Here is my servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<context:component-scan base-package="controllers"/>
</beans:beans>
Here is my HomeController class
#Controller
public class HomeController {
private UserService userService;
#RequestMapping(value = "/home")
public ModelAndView homePage(HttpServletRequest request, HttpServletResponse response, HttpSession session){
User user = userService.fetchUser();
return new ModelAndView("home", "displayName", user.getUserName());
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
Here is my User class
public class User {
private String userName;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Here is my UserService class
public class UserService {
public User fetchUser(){
User user = new User();
user.setUserName("test");
return user;
}
}
You miss the #Autowired annotation in your HomeController:
#Autowired
private UserService userService;
Remove homeController bean defintiion.
Since you are using <context:component-scan base-package="controllers"/> there is no need to declare homeController bean - it will be created automatically because it's annotated with annotation #Controller.
Autowire UserService into HomeController using#Autowired` annotation. There are 3 ways you can do it:
field injection:
#Autowired
private UserService userService;
setter injection
#Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
constructor injection:
#Autowired
public HomeController(UserService userService) {
this.userService = userService;
}
Preferred way is to always use constructor injection
Remove UserService getters and setters in HomeController.
In the end, HomeController class should look like:
#Controller
public class HomeController {
private final UserService userService;
#Autowired
public HomeController(UserService userService) {
this.userService = userService;
}
#RequestMapping(value = "/home")
public ModelAndView homePage(HttpServletRequest request, HttpServletResponse response, HttpSession session){
User user = userService.fetchUser();
return new ModelAndView("home", "displayName", user.getUserName());
}
}
This way Eclipse marks the default constructor line with error. If I remove the default constructor glassfish says it cannot initialize UserService because there is no default constructor.
public class UserService {
public UserService(){}
private final UserDao userDao;
#Autowired
public UserService(UserDao userDao){
this.userDao = userDao;
}
public User fetchUser(){
User user = userDao.fetchUser();
return user;
}
}

#Autowired annotation in spring

i am relatively new in spring and i have problems with understanding fundamentals of spring mvc..
My controller
#Controller
public class HomeController {
private ContactManager contactManager;
#Autowired
public void setContactManager(ContactManager contactManager) {
this.contactManager = contactManager;
}
#RequestMapping(value="/")
public ModelAndView listContact(ModelAndView model) throws IOException {
List<Contact> listContact = contactManager.list();
model.addObject("listContact", listContact);
model.setViewName("home");
return model;
}
...
Contact ManagerImpl, and implementation of interface method
public class ContactManagerImpl implements ContactManager {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
...
ContactManager
public interface ContactManager {
public void saveOrUpdate(Contact contact);
public void delete(int contactId);
public Contact get(int contactId);
public List<Contact> list();
}
And root-context.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="sec"/>
</bean>
<bean id="managmentService" class="spring.contact.impl.model.ContactManagerImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
My problem is that i get error:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of
type [spring.contact.api.ContactManager] found for dependency: expected at least 1
bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
And of course the problem is with #Autowired annotations. How can i fix it ? When i removed #Autowired annotations i get another error: NullPointerException (manager in HomeController).
Your Controller should be..
#Controller
public class HomeController {
#Autowired
#Qualifier("managmentService")
private ContactManager contactManager;
#RequestMapping(value="/")
public ModelAndView listContact(ModelAndView model) throws IOException {
List<Contact> listContact = contactManager.list();
model.addObject("listContact", listContact);
model.setViewName("home");
return model;
}
...
In your configuration add also <context:annotation-config />that is used in order to be able to use #Autowired annotation.
An example of <context:annotation-config />
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
Move the #Autowired annotation to the declaration for ContactManager.
You won't need the setter, delete it.

Spring data MongoDb cannot convert proxy bean

I'm using Spring AOP with AspectJ and Spring Data MongoDb and am having a world of trouble persisting objects.
In this case, I have an AclEntryDaoImpl that exposes AclEntryImpl. When AclEntryImpl is provided a Principal that is a standard Java object (a "non-Spring" bean), mongoTemplate.save() works as expected. However when Principal is a Spring bean, Mongo is unable to convert the object and results in a MappingException org.springframework.data.mapping.model.MappingException: No id property found on class class com.sun.proxy.$Proxy33. All my objects need to be Spring beans so that (a) I keep my objects decoupled and (b) my AOP (LoggingAspect) is invoked.
Lastly, I cannot take advantage of Spring converters because Mongo sees the target object AclEntryImpl as a proxy com.sun.proxy.$Proxy33 and so Converter<Principal, DBObject> is never invoked.
Any and all help would be greatly appreciated!
Snippets:
Here's my Spring XML configuration:
<beans>
<context:component-scan base-package="a.b" />
<context:property-placeholder location="config.properties" />
<aop:aspectj-autoproxy />
<bean id="loggingAspect" class="a.b.LoggingAspect" />
<mongo:db-factory host="${database.host}" port="${database.port}" dbname="${database.dbname}" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<bean id="aclEntryDao" class="a.b.AclEntryDaoImpl">
<lookup-method name="createAclEntry" bean="aclEntry" />
</bean>
</beans>
AclEntryImpl:
#Document
#Component
#Scope("prototype")
public class AclEntryImpl implements AclEntry {
#Id
private String id;
private String service;
#DBRef #Expose
private Principal principal;
#Expose
private boolean accessGranted;
#Expose
private List<Permission> permissions;
#Override #Loggable #MongoSaveReturned
public AclEntry save() {
return this;
}
...getters and setters...
}
AclEntryDaoImpl:
#Repository
public abstract class AclEntryDaoImpl implements AclEntryDao {
#Override #Loggable
public AclEntry addEntry(String serviceName, Principal principal, Permission[] permissions, boolean accessGranted) throws Exception {
AclEntry entry = createAclEntry(); //<-- Spring lookup-method
entry.setService(serviceName);
entry.setPrincipal(principal); //<-- com.sun.proxy.$Proxy33
entry.setAccessGranted(accessGranted);
for (Permission permission : permissions) {
if (!entry.addPermission(permission)) {
return null;
}
}
return entry.save();
}
... other DAO methods ...
}
LoggingAspect:
#Aspect
public class LoggingAspect {
#Autowired
private MongoTemplate mongoTemplate;
#Pointcut("execution(!void a.b..*.*(..))")
public void returningMethods() {}
#AfterReturning(pointcut="returningMethods() && #annotation(MongoSaveReturned)", returning="retVal")
public Object mongoSaveReturnedAdvice(Object retVal) {
Logger logger = null;
try {
logger = getLogger(retVal);
mongoTemplate.save(retVal); //<-- throws MappingException
log(logger, "save: " + retVal.toString());
} catch (Exception e) {
log(logger, "throw: " + e.toString());
}
return retVal;
}
... other logging methods ...
}

Resources