EJB are wrapper around any kind of component, if you need data access, directory, resources, services, JMS, RMI, SOA etc. EJB Provides a standard way to wrap these thing under common umbrella which has many features. It can be compared to POJO but with lot of advance feature which you dont need write.

@Stateless
public class MyAccountsBean {

    @EJB SomeOtherBeanClass someOtherBean;
    @Resource UserTransaction jtaTx;
    @PersistenceContext(unitName="AccountsPU") EntityManager em;
    @Resource QueueConnectionFactory accountsJMSfactory;
    @Resource Queue accountPaymentDestinationQueue;

    public List<Account> processAccounts(DepartmentId id) {
        // Use all of above instance variables with no additional setup.
        // They automatically partake in a (server coordinated) JTA transaction
    }
}
@EJB MyAccountsBean accountsBean;    

EJB sounds very nice starting from EJB 3.0, EJB 2.0 Entity bean has moved to separate Java EE specification JPA entities. EJB mainly had 3 type of bean.

Stateless

It has following methods

package com.javatpoint;  
import javax.ejb.Remote;  
  
@Remote  
public interface AdderImplRemote {  
int add(int a,int b);  
}  

package com.javatpoint;  
import javax.ejb.Stateless;  
  
@Stateless(mappedName="st1")  
public class AdderImpl implements AdderImplRemote {  
  public int add(int a,int b){  
      return a+b;  
  }  
}  

package com.javatpoint;  
import javax.naming.Context;  
import javax.naming.InitialContext;  
  
public class Test {  
public static void main(String[] args)throws Exception {  
    Context context=new InitialContext();  
    AdderImplRemote remote=(AdderImplRemote)context.lookup("st1");  
    System.out.println(remote.add(32,32));  
}  
}  

Stateful

It has following methods.

package com.javatpoint;  
import javax.ejb.Remote;  
@Remote  
public interface BankRemote {  
    boolean withdraw(int amount);  
    void deposit(int amount);  
    int getBalance();  
}  

package com.javatpoint;  
import javax.ejb.Stateful;  
@Stateful(mappedName = "stateful123")  
public class Bank implements BankRemote {  
    private int amount=0;  
    public boolean withdraw(int amount){  
        if(amount<=this.amount){  
            this.amount-=amount;  
            return true;  
        }else{  
            return false;  
        }  
    }  
    public void deposit(int amount){  
        this.amount+=amount;  
    }  
    public int getBalance(){  
        return amount;  
    }  
}  

package com.javatpoint;  
import java.io.IOException;  
import javax.ejb.EJB;  
import javax.naming.InitialContext;  
import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
@WebServlet("/OpenAccount")  
public class OpenAccount extends HttpServlet {  
    //@EJB(mappedName="stateful123")  
    //BankRemote b;  
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
        try{  
            InitialContext context=new InitialContext();  
            BankRemote b=(BankRemote)context.lookup("stateful123");  
              
            request.getSession().setAttribute("remote",b);  
            request.getRequestDispatcher("/operation.jsp").forward(request, response);  
          
        }catch(Exception e){System.out.println(e);}  
    }  
}