0

I don't know if it is the better way to implement my solution:

@Component
@Scope("singleton")
public class GetFromJson implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = -8203722696439228358L;
    Map<String, Map<String, ArrayList<String>>> jsonMap;

    public Map<String, Map<String, ArrayList<String>>> getJsonMap() { 
        return jsonMap;
    }

    public void setJsonMap(Map<String, Map<String, ArrayList<String>>> jsonMap) {
       this.jsonMap= jsonMap;
    }    
}

The class is Serializable because I get the content from a Json from a database and I map the content in an Object GetFromJson (I need do the query in database only one time). For this reason I need use the Object in all my APp, for this reason I think that I need use a Singleton

Somebody publish to me a library to get the JSON from database. the JSON object parse to Map<String, Map<String, ArrayList<String>>> for this reason I create my GetFromJson class.

Now I have many rest Service, in my rest services I need use my object: GetFromJson to get the content of jsonMap.

I have many questions.

With the annotation @Scope("singleton") I guarantee have the GetFromJson only one instance available in all my app?

Or what is the better way to have in Spring a singleton and session object available in my app?

To access to get the content of jsonMap of GetFromJson is enough use

@Autowired
private GetFromJson jsonObject;

Or how can I get my singleton class?

and in my rest method service use:

 jsonObject.getJsonMap();

How can Initialize my singleton, because i am trying initialize my object with:

@Autowired
private GetFromJson jsonObject;


public methodToInitialize(){
    jsonObject = methodLibraryFromDatabase(GetFromJson.class);
}

ANd the IDE tell to me that the field initialization is not used

I need the same logic, but with session Object, I think that if I understand the singleton implementation with my session object will be the same but only changing the anotation to: @Scope("session")

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Code Geas Coder
  • 1,839
  • 4
  • 23
  • 29

2 Answers2

1

I think what OP is wants to initialize database based POJO once in application lifecycle and autowire it where needed.

Typically this is done by creating a bean (which are singletons unless otherwise specified) and autowiring it where needed.

This sample should get you started.

@Configuration // beans are declerated in @Configuration classes
public class GetJsonInitializer {

    @Bean // singleton by default
    public GetFromJson jsonMap(){
        GetFromJson jsonObject = methodLibraryDatabase(GetFromJson.class);
        return jsonOBject;
    }
}

Now autowire GetFromJson in any Spring service/component etc.

@Service
public class SomeService {
    @Autowired
    private GetFromJson jsonMap;
}

Hope this helps!

Archit
  • 913
  • 1
  • 10
  • 20
  • Ok. I understand. And If I add the annotation to the Bean with scope("session") @Bean @scope("session") public GetFromJson jsonMap(){ It change the scope of the bean? – Code Geas Coder Jun 29 '18 at 22:45
  • Yes. A newly created bean woukd be injected in every new session – Archit Jul 01 '18 at 07:00
  • Noo, i am trying, but it show me: scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; – Code Geas Coder Jul 03 '18 at 15:59
  • Scope session only works in a web service. Also this may help you https://stackoverflow.com/a/21358274/776548 – Archit Jul 04 '18 at 18:44
0

a bean annotated with session scope is going to be bound to user's session life cycle, that is, for each user accessing your app, you'll have an instance of this class. If you want to guarantee only one instance of this bean in your application (at JVM level) you just need to remove the @Scope annotation. However, if you want to mix singletons with session scoped beans, then you should just let spring handle everything seamless for you, your session scope beans will only be destroyed when the user session ends.

The best way to handle initialization code in your bean is in a public method annotated with javax.annotation.PostConstruct

@PostConstruct
public void setUp() {
    //initialization code
}

In order to handle a clean up code when a bean is going to be destroyed, you should make your class implement org.springframework.beans.factory.DisposableBean or add a method annotated with javax.annotation.PreDestroy

@PreDestroy
public void onDestroy() {
    //clean up code
}

I hope this has helped you out!

s_bighead
  • 1,014
  • 13
  • 24
  • And using the Autowired in the restService is created the instance? I can change the object instance using injection in the different services? – Code Geas Coder Jun 29 '18 at 19:06
  • If the bean is session scoped spring will create and change the instances reference whenever it's needed to. However, if you want a shorter lifecycle, that is, for each reference always a new instance, you should look for prototype scoped beans and factory beans. If you want to create the instance on your own, the next answer by @Archit can steer you how to do it correctly. Additionally, there are other ways to force a bean to be destroyed like this one: https://stackoverflow.com/a/22746820/3335350 . – s_bighead Jun 29 '18 at 22:38